1; RUN: llc -mtriple=thumb-eabi %s -verify-machineinstrs -o - | \ 2; RUN: FileCheck %s -check-prefix CHECK --check-prefix CHECK-EABI 3; RUN: llc -mtriple=thumb-apple-darwin %s -verify-machineinstrs -o - | \ 4; RUN: FileCheck %s -check-prefix CHECK -check-prefix CHECK-DARWIN 5 6define i64 @f1() { 7entry: 8 ret i64 0 9; CHECK-LABEL: f1: 10; CHECK: movs r0, #0 11; CHECK: movs r1, r0 12} 13 14define i64 @f2() { 15entry: 16 ret i64 1 17; CHECK-LABEL: f2: 18; CHECK: movs r0, #1 19; CHECK: movs r1, #0 20} 21 22define i64 @f3() { 23entry: 24 ret i64 2147483647 25; CHECK-LABEL: f3: 26; CHECK: ldr r0, 27; CHECK: movs r1, #0 28} 29 30define i64 @f4() { 31entry: 32 ret i64 2147483648 33; CHECK-LABEL: f4: 34; CHECK: movs r0, #1 35; CHECK: lsls r0, r0, #31 36; CHECK: movs r1, #0 37} 38 39define i64 @f5() { 40entry: 41 ret i64 9223372036854775807 42; CHECK-LABEL: f5: 43; CHECK: movs r0, #0 44; CHECK: mvns r0, r0 45; CHECK: ldr r1, 46} 47 48define i64 @f6(i64 %x, i64 %y) { 49entry: 50 %tmp1 = add i64 %y, 1 ; <i64> [#uses=1] 51 ret i64 %tmp1 52; CHECK-LABEL: f6: 53; CHECK: movs r1, #0 54; CHECK: adds r0, r2, #1 55; CHECK: adcs r1, r3 56} 57 58define i64 @f6a(i64 %x, i64 %y) { 59entry: 60 %tmp1 = add i64 %y, 10 61 ret i64 %tmp1 62; CHECK-LABEL: f6a: 63; CHECK: movs r0, r2 64; CHECK: movs r1, #0 65; CHECK: adds r0, #10 66; CHECK: adcs r1, r3 67} 68 69define i64 @f6b(i64 %x, i64 %y) { 70entry: 71 %tmp1 = add i64 %y, 1000 72 ret i64 %tmp1 73; CHECK-LABEL: f6b: 74; CHECK: movs r0, #125 75; CHECK: lsls r0, r0, #3 76; CHECK: movs r1, #0 77; CHECK: adds r0, r2, r0 78; CHECK: adcs r1, r3 79} 80 81define void @f7() { 82entry: 83 %tmp = call i64 @f8( ) ; <i64> [#uses=0] 84 ret void 85; CHECK-LABEL: f7: 86; CHECK: bl 87} 88 89declare i64 @f8() 90 91define i64 @f9(i64 %a, i64 %b) { 92entry: 93 %tmp = sub i64 %a, %b ; <i64> [#uses=1] 94 ret i64 %tmp 95; CHECK-LABEL: f9: 96; CHECK: subs r0, r0, r2 97; CHECK: sbcs r1, r3 98} 99 100define i64 @f9a(i64 %x, i64 %y) { ; ADDC with small negative imm => SUBS imm 101entry: 102 %tmp1 = sub i64 %y, 10 103 ret i64 %tmp1 104; CHECK-LABEL: f9a: 105; CHECK: movs r1, r3 106; CHECK: movs r0, r2 107; CHECK: movs r2, #0 108; CHECK: subs r0, #10 109; CHECK: sbcs r1, r2 110} 111 112define i64 @f9b(i64 %x, i64 %y) { ; ADDC with big negative imm => SUBS reg 113entry: 114 %tmp1 = sub i64 1000, %y 115 ret i64 %tmp1 116; CHECK-LABEL: f9b: 117; CHECK: movs r0, #125 118; CHECK: lsls r0, r0, #3 119; CHECK: movs r1, #0 120; CHECK: subs r0, r0, r2 121; CHECK: sbcs r1, r3 122} 123 124define i64 @f9c(i64 %x, i32 %y) { ; SUBS with small positive imm => SUBS imm 125entry: 126 %conv = sext i32 %y to i64 127 %shl = shl i64 %conv, 32 128 %or = or i64 %shl, 1 129 %sub = sub nsw i64 %x, %or 130 ret i64 %sub 131; CHECK-LABEL: f9c: 132; CHECK: subs r0, r0, #1 133; CHECK: sbcs r1, r2 134} 135 136define i64 @f9d(i64 %x, i32 %y) { ; SUBS with small negative imm => ADDS imm 137entry: 138 %conv = sext i32 %y to i64 139 %shl = shl i64 %conv, 32 140 %or = or i64 %shl, 4294967295 141 %sub = sub nsw i64 %x, %or 142 ret i64 %sub 143; CHECK-LABEL: f9d: 144; CHECK: adds r0, r0, #1 145; CHECK: sbcs r1, r2 146} 147 148define i64 @f(i32 %a, i32 %b) { 149entry: 150 %tmp = sext i32 %a to i64 ; <i64> [#uses=1] 151 %tmp1 = sext i32 %b to i64 ; <i64> [#uses=1] 152 %tmp2 = mul i64 %tmp1, %tmp ; <i64> [#uses=1] 153 ret i64 %tmp2 154; CHECK-LABEL: f: 155; CHECK-V6: bl __aeabi_lmul 156; CHECK-DARWIN: __muldi3 157} 158 159define i64 @g(i32 %a, i32 %b) { 160entry: 161 %tmp = zext i32 %a to i64 ; <i64> [#uses=1] 162 %tmp1 = zext i32 %b to i64 ; <i64> [#uses=1] 163 %tmp2 = mul i64 %tmp1, %tmp ; <i64> [#uses=1] 164 ret i64 %tmp2 165; CHECK-LABEL: g: 166; CHECK-V6: bl __aeabi_lmul 167; CHECK-DARWIN: __muldi3 168} 169 170define i64 @f10() { 171entry: 172 %a = alloca i64, align 8 ; <i64*> [#uses=1] 173 %retval = load i64, i64* %a ; <i64> [#uses=1] 174 ret i64 %retval 175; CHECK-LABEL: f10: 176; CHECK-EABI: sub sp, #8 177; CHECK-DARWIN: add r7, sp, #4 178; CHECK: ldr r0, [sp] 179; CHECK: ldr r1, [sp, #4] 180; CHECK-EABI: add sp, #8 181; CHECK-DARWIN: mov sp, r4 182} 183 184define i64 @f11(i64 %x, i64 %y) { 185entry: 186 %tmp1 = add i64 -1000, %y 187 %tmp2 = add i64 %tmp1, -1000 188 ret i64 %tmp2 189; CHECK-LABEL: f11: 190; CHECK: movs r1, r3 191; CHECK: movs r0, #125 192; CHECK: lsls r0, r0, #3 193; CHECK: movs r3, #0 194; CHECK: subs r2, r2, r0 195; CHECK: sbcs r1, r3 196; CHECK: subs r0, r2, r0 197; CHECK: sbcs r1, r3 198} 199 200; "sub 2147483648" has to be lowered into "add -2147483648" 201define i64 @f12(i64 %x, i64 %y) { 202entry: 203 %tmp1 = sub i64 %x, 2147483648 204 ret i64 %tmp1 205; CHECK-LABEL: f12: 206; CHECK: movs r2, #1 207; CHECK: lsls r2, r2, #31 208; CHECK: movs r3, #0 209; CHECK: adds r0, r0, r2 210; CHECK: sbcs r1, r3 211} 212 213declare void @f13(i64 %x) 214 215define void @f14(i1 %x, i64 %y) #0 { 216; CHECK-LABEL: f14: 217entry: 218 %a = add i64 %y, 47 219 call void @f13(i64 %a) 220; CHECK: bl 221 br i1 %x, label %if.end, label %if.then 222 223if.then: 224 call void @f13(i64 %y) 225; CHECK: bl 226 br label %if.end 227 228if.end: 229 %b = add i64 %y, 45 230 call void @f13(i64 %b) 231; CHECK: adds 232; CHECK: adcs 233; CHECK: bl 234 %c = add i64 %y, 47 235 call void @f13(i64 %c) 236; CHECK: adds 237; CHECK-NEXT: adcs 238; CHECK: bl 239 ret void 240} 241 242attributes #0 = { optsize } 243