1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=thumbv6m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-T1 3; RUN: llc -mtriple=thumbv7m-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-T2 4; RUN: llc -mtriple=armv7a-none-eabi %s -o - | FileCheck %s --check-prefixes=CHECK-A 5 6define i32 @test_add_i3(i1 %tst, i32 %a, i32 %b) { 7; CHECK-T1-LABEL: test_add_i3: 8; CHECK-T1: @ %bb.0: 9; CHECK-T1-NEXT: .save {r4, lr} 10; CHECK-T1-NEXT: push {r4, lr} 11; CHECK-T1-NEXT: lsls r0, r0, #31 12; CHECK-T1-NEXT: bne .LBB0_2 13; CHECK-T1-NEXT: @ %bb.1: 14; CHECK-T1-NEXT: movs r0, #3 15; CHECK-T1-NEXT: bics r2, r0 16; CHECK-T1-NEXT: mov r4, r2 17; CHECK-T1-NEXT: b .LBB0_3 18; CHECK-T1-NEXT: .LBB0_2: 19; CHECK-T1-NEXT: mov r4, r1 20; CHECK-T1-NEXT: movs r0, #6 21; CHECK-T1-NEXT: bics r4, r0 22; CHECK-T1-NEXT: .LBB0_3: 23; CHECK-T1-NEXT: mov r0, r4 24; CHECK-T1-NEXT: bl foo 25; CHECK-T1-NEXT: adds r0, r4, #2 26; CHECK-T1-NEXT: pop {r4, pc} 27; 28; CHECK-T2-LABEL: test_add_i3: 29; CHECK-T2: @ %bb.0: 30; CHECK-T2-NEXT: .save {r4, lr} 31; CHECK-T2-NEXT: push {r4, lr} 32; CHECK-T2-NEXT: bic r4, r2, #3 33; CHECK-T2-NEXT: lsls r0, r0, #31 34; CHECK-T2-NEXT: it ne 35; CHECK-T2-NEXT: bicne r4, r1, #6 36; CHECK-T2-NEXT: mov r0, r4 37; CHECK-T2-NEXT: bl foo 38; CHECK-T2-NEXT: adds r0, r4, #2 39; CHECK-T2-NEXT: pop {r4, pc} 40; 41; CHECK-A-LABEL: test_add_i3: 42; CHECK-A: @ %bb.0: 43; CHECK-A-NEXT: .save {r4, lr} 44; CHECK-A-NEXT: push {r4, lr} 45; CHECK-A-NEXT: bic r4, r2, #3 46; CHECK-A-NEXT: tst r0, #1 47; CHECK-A-NEXT: bicne r4, r1, #6 48; CHECK-A-NEXT: mov r0, r4 49; CHECK-A-NEXT: bl foo 50; CHECK-A-NEXT: orr r0, r4, #2 51; CHECK-A-NEXT: pop {r4, pc} 52 %tmp = and i32 %a, -7 53 %tmp1 = and i32 %b, -4 54 %int = select i1 %tst, i32 %tmp, i32 %tmp1 55 56 ; Call to force %int into a register that isn't r0 so using the i3 form is a 57 ; good idea. 58 call void @foo(i32 %int) 59 %res = or i32 %int, 2 60 ret i32 %res 61} 62 63define i32 @test_add_i8(i32 %a, i32 %b, i1 %tst) { 64; CHECK-T1-LABEL: test_add_i8: 65; CHECK-T1: @ %bb.0: 66; CHECK-T1-NEXT: lsls r2, r2, #31 67; CHECK-T1-NEXT: bne .LBB1_2 68; CHECK-T1-NEXT: @ %bb.1: 69; CHECK-T1-NEXT: ldr r0, .LCPI1_0 70; CHECK-T1-NEXT: ands r1, r0 71; CHECK-T1-NEXT: mov r0, r1 72; CHECK-T1-NEXT: adds r0, #12 73; CHECK-T1-NEXT: bx lr 74; CHECK-T1-NEXT: .LBB1_2: 75; CHECK-T1-NEXT: movs r1, #255 76; CHECK-T1-NEXT: bics r0, r1 77; CHECK-T1-NEXT: adds r0, #12 78; CHECK-T1-NEXT: bx lr 79; CHECK-T1-NEXT: .p2align 2 80; CHECK-T1-NEXT: @ %bb.3: 81; CHECK-T1-NEXT: .LCPI1_0: 82; CHECK-T1-NEXT: .long 4294966784 @ 0xfffffe00 83; 84; CHECK-T2-LABEL: test_add_i8: 85; CHECK-T2: @ %bb.0: 86; CHECK-T2-NEXT: movw r3, #511 87; CHECK-T2-NEXT: bics r1, r3 88; CHECK-T2-NEXT: lsls r2, r2, #31 89; CHECK-T2-NEXT: it ne 90; CHECK-T2-NEXT: bicne r1, r0, #255 91; CHECK-T2-NEXT: add.w r0, r1, #12 92; CHECK-T2-NEXT: bx lr 93; 94; CHECK-A-LABEL: test_add_i8: 95; CHECK-A: @ %bb.0: 96; CHECK-A-NEXT: bfc r1, #0, #9 97; CHECK-A-NEXT: tst r2, #1 98; CHECK-A-NEXT: bicne r1, r0, #255 99; CHECK-A-NEXT: orr r0, r1, #12 100; CHECK-A-NEXT: bx lr 101 %tmp = and i32 %a, -256 102 %tmp1 = and i32 %b, -512 103 %int = select i1 %tst, i32 %tmp, i32 %tmp1 104 %res = or i32 %int, 12 105 ret i32 %res 106} 107 108define i32 @test_add_i12(i32 %a, i32 %b, i1 %tst) { 109; CHECK-T1-LABEL: test_add_i12: 110; CHECK-T1: @ %bb.0: 111; CHECK-T1-NEXT: lsls r2, r2, #31 112; CHECK-T1-NEXT: bne .LBB2_2 113; CHECK-T1-NEXT: @ %bb.1: 114; CHECK-T1-NEXT: ldr r0, .LCPI2_1 115; CHECK-T1-NEXT: ands r1, r0 116; CHECK-T1-NEXT: mov r0, r1 117; CHECK-T1-NEXT: b .LBB2_3 118; CHECK-T1-NEXT: .LBB2_2: 119; CHECK-T1-NEXT: ldr r1, .LCPI2_0 120; CHECK-T1-NEXT: ands r0, r1 121; CHECK-T1-NEXT: .LBB2_3: 122; CHECK-T1-NEXT: ldr r1, .LCPI2_2 123; CHECK-T1-NEXT: adds r0, r0, r1 124; CHECK-T1-NEXT: bx lr 125; CHECK-T1-NEXT: .p2align 2 126; CHECK-T1-NEXT: @ %bb.4: 127; CHECK-T1-NEXT: .LCPI2_0: 128; CHECK-T1-NEXT: .long 4294963200 @ 0xfffff000 129; CHECK-T1-NEXT: .LCPI2_1: 130; CHECK-T1-NEXT: .long 4294959104 @ 0xffffe000 131; CHECK-T1-NEXT: .LCPI2_2: 132; CHECK-T1-NEXT: .long 854 @ 0x356 133; 134; CHECK-T2-LABEL: test_add_i12: 135; CHECK-T2: @ %bb.0: 136; CHECK-T2-NEXT: movw r3, #8191 137; CHECK-T2-NEXT: bics r1, r3 138; CHECK-T2-NEXT: movw r12, #4095 139; CHECK-T2-NEXT: lsls r2, r2, #31 140; CHECK-T2-NEXT: it ne 141; CHECK-T2-NEXT: bicne.w r1, r0, r12 142; CHECK-T2-NEXT: addw r0, r1, #854 143; CHECK-T2-NEXT: bx lr 144; 145; CHECK-A-LABEL: test_add_i12: 146; CHECK-A: @ %bb.0: 147; CHECK-A-NEXT: bfc r0, #0, #12 148; CHECK-A-NEXT: bfc r1, #0, #13 149; CHECK-A-NEXT: tst r2, #1 150; CHECK-A-NEXT: movne r1, r0 151; CHECK-A-NEXT: movw r0, #854 152; CHECK-A-NEXT: orr r0, r1, r0 153; CHECK-A-NEXT: bx lr 154 %tmp = and i32 %a, -4096 155 %tmp1 = and i32 %b, -8192 156 %int = select i1 %tst, i32 %tmp, i32 %tmp1 157 %res = or i32 %int, 854 158 ret i32 %res 159} 160 161define i32 @oradd(i32 %i, i32 %y) { 162; CHECK-T1-LABEL: oradd: 163; CHECK-T1: @ %bb.0: @ %entry 164; CHECK-T1-NEXT: lsls r0, r0, #1 165; CHECK-T1-NEXT: adds r0, r1, r0 166; CHECK-T1-NEXT: adds r0, r0, #1 167; CHECK-T1-NEXT: bx lr 168; 169; CHECK-T2-LABEL: oradd: 170; CHECK-T2: @ %bb.0: @ %entry 171; CHECK-T2-NEXT: add.w r0, r1, r0, lsl #1 172; CHECK-T2-NEXT: adds r0, #1 173; CHECK-T2-NEXT: bx lr 174; 175; CHECK-A-LABEL: oradd: 176; CHECK-A: @ %bb.0: @ %entry 177; CHECK-A-NEXT: add r0, r1, r0, lsl #1 178; CHECK-A-NEXT: add r0, r0, #1 179; CHECK-A-NEXT: bx lr 180entry: 181 %mul = shl i32 %i, 1 182 %or = or i32 %mul, 1 183 %add = add i32 %or, %y 184 ret i32 %add 185} 186 187define i32 @orgep(i32 %i, ptr %x, ptr %y) { 188; CHECK-T1-LABEL: orgep: 189; CHECK-T1: @ %bb.0: @ %entry 190; CHECK-T1-NEXT: lsls r0, r0, #3 191; CHECK-T1-NEXT: adds r0, r1, r0 192; CHECK-T1-NEXT: ldr r0, [r0, #4] 193; CHECK-T1-NEXT: bx lr 194; 195; CHECK-T2-LABEL: orgep: 196; CHECK-T2: @ %bb.0: @ %entry 197; CHECK-T2-NEXT: add.w r0, r1, r0, lsl #3 198; CHECK-T2-NEXT: ldr r0, [r0, #4] 199; CHECK-T2-NEXT: bx lr 200; 201; CHECK-A-LABEL: orgep: 202; CHECK-A: @ %bb.0: @ %entry 203; CHECK-A-NEXT: add r0, r1, r0, lsl #3 204; CHECK-A-NEXT: ldr r0, [r0, #4] 205; CHECK-A-NEXT: bx lr 206entry: 207 %mul = shl i32 %i, 1 208 %add = or i32 %mul, 1 209 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add 210 %0 = load i32, ptr %arrayidx, align 8 211 ret i32 %0 212} 213 214define i32 @orgeps(i32 %i, ptr %x, ptr %y) { 215; CHECK-T1-LABEL: orgeps: 216; CHECK-T1: @ %bb.0: @ %entry 217; CHECK-T1-NEXT: lsls r0, r0, #3 218; CHECK-T1-NEXT: adds r0, r1, r0 219; CHECK-T1-NEXT: ldr r1, [r0, #4] 220; CHECK-T1-NEXT: ldr r0, [r0, #8] 221; CHECK-T1-NEXT: adds r0, r0, r1 222; CHECK-T1-NEXT: bx lr 223; 224; CHECK-T2-LABEL: orgeps: 225; CHECK-T2: @ %bb.0: @ %entry 226; CHECK-T2-NEXT: add.w r0, r1, r0, lsl #3 227; CHECK-T2-NEXT: ldrd r0, r1, [r0, #4] 228; CHECK-T2-NEXT: add r0, r1 229; CHECK-T2-NEXT: bx lr 230; 231; CHECK-A-LABEL: orgeps: 232; CHECK-A: @ %bb.0: @ %entry 233; CHECK-A-NEXT: add r0, r1, r0, lsl #3 234; CHECK-A-NEXT: ldrd r0, r1, [r0, #4] 235; CHECK-A-NEXT: add r0, r1, r0 236; CHECK-A-NEXT: bx lr 237entry: 238 %mul = shl i32 %i, 1 239 %add = or i32 %mul, 1 240 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add 241 %0 = load i32, ptr %arrayidx, align 8 242 %add2 = add i32 %mul, 2 243 %arrayidx3 = getelementptr inbounds i32, ptr %x, i32 %add2 244 %1 = load i32, ptr %arrayidx3, align 8 245 %add4 = add i32 %1, %0 246 ret i32 %add4 247} 248 249define i32 @multiuse(i32 %i, ptr %x, ptr %y) { 250; CHECK-T1-LABEL: multiuse: 251; CHECK-T1: @ %bb.0: @ %entry 252; CHECK-T1-NEXT: lsls r0, r0, #1 253; CHECK-T1-NEXT: adds r0, r0, #1 254; CHECK-T1-NEXT: lsls r2, r0, #2 255; CHECK-T1-NEXT: ldr r1, [r1, r2] 256; CHECK-T1-NEXT: adds r0, r0, r1 257; CHECK-T1-NEXT: bx lr 258; 259; CHECK-T2-LABEL: multiuse: 260; CHECK-T2: @ %bb.0: @ %entry 261; CHECK-T2-NEXT: lsls r0, r0, #1 262; CHECK-T2-NEXT: adds r0, #1 263; CHECK-T2-NEXT: ldr.w r1, [r1, r0, lsl #2] 264; CHECK-T2-NEXT: add r0, r1 265; CHECK-T2-NEXT: bx lr 266; 267; CHECK-A-LABEL: multiuse: 268; CHECK-A: @ %bb.0: @ %entry 269; CHECK-A-NEXT: mov r2, #1 270; CHECK-A-NEXT: orr r0, r2, r0, lsl #1 271; CHECK-A-NEXT: ldr r1, [r1, r0, lsl #2] 272; CHECK-A-NEXT: add r0, r0, r1 273; CHECK-A-NEXT: bx lr 274entry: 275 %mul = shl i32 %i, 1 276 %add = or i32 %mul, 1 277 %arrayidx = getelementptr inbounds i32, ptr %x, i32 %add 278 %0 = load i32, ptr %arrayidx, align 8 279 %r = add i32 %add, %0 280 ret i32 %r 281} 282 283declare void @foo(i32) 284