200 lines · plain
1; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-MACHO2; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM --check-prefix=ARM-ELF3; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB4 5; Very basic fast-isel functionality.6define i32 @test0(i32 %a, i32 %b) nounwind {7entry:8 %a.addr = alloca i32, align 49 %b.addr = alloca i32, align 410 store i32 %a, ptr %a.addr11 store i32 %b, ptr %b.addr12 %tmp = load i32, ptr %a.addr13 %tmp1 = load i32, ptr %b.addr14 %add = add nsw i32 %tmp, %tmp115 ret i32 %add16}17 18; Check truncate to bool19define void @test1(i32 %tmp) nounwind {20entry:21%tobool = trunc i32 %tmp to i122br i1 %tobool, label %if.then, label %if.end23 24if.then: ; preds = %entry25call void @test1(i32 0)26br label %if.end27 28if.end: ; preds = %if.then, %entry29ret void30; ARM-LABEL: test1:31; ARM: tst r0, #132; THUMB-LABEL: test1:33; THUMB: tst.w r0, #134}35 36; Check some simple operations with immediates37define void @test2(i32 %tmp, ptr %ptr) nounwind {38; THUMB-LABEL: test2:39; ARM-LABEL: test2:40 41b1:42 %a = add i32 %tmp, 409643 store i32 %a, ptr %ptr44 br label %b245 46; THUMB: add.w {{.*}} #409647; ARM: add {{.*}} #409648 49b2:50 %b = add i32 %tmp, 409551 store i32 %b, ptr %ptr52 br label %b353; THUMB: addw {{.*}} #409554; ARM: movw {{.*}} #409555; ARM: add56 57b3:58 %c = or i32 %tmp, 459 store i32 %c, ptr %ptr60 ret void61 62; THUMB: orr {{.*}} #463; ARM: orr {{.*}} #464}65 66define void @test3(i32 %tmp, ptr %ptr1, ptr %ptr2, ptr %ptr3) nounwind {67; THUMB-LABEL: test3:68; ARM-LABEL: test3:69 70bb1:71 %a1 = trunc i32 %tmp to i1672 %a2 = trunc i16 %a1 to i873 %a3 = trunc i8 %a2 to i174 %a4 = zext i1 %a3 to i875 store i8 %a4, ptr %ptr376 %a5 = zext i8 %a4 to i1677 store i16 %a5, ptr %ptr278 %a6 = zext i16 %a5 to i3279 store i32 %a6, ptr %ptr180 br label %bb281 82; THUMB: and83; THUMB: strb84; THUMB: and{{.*}}, #25585; THUMB: strh86; THUMB: uxth87; ARM: and88; ARM: strb89; ARM: and{{.*}}, #25590; ARM: strh91; ARM: uxth92 93bb2:94 %b1 = trunc i32 %tmp to i1695 %b2 = trunc i16 %b1 to i896 store i8 %b2, ptr %ptr397 %b3 = sext i8 %b2 to i1698 store i16 %b3, ptr %ptr299 %b4 = sext i16 %b3 to i32100 store i32 %b4, ptr %ptr1101 br label %bb3102 103; THUMB: strb104; THUMB: sxtb105; THUMB: strh106; THUMB: sxth107; ARM: strb108; ARM: sxtb109; ARM: strh110; ARM: sxth111 112bb3:113 %c1 = load i8, ptr %ptr3114 %c2 = load i16, ptr %ptr2115 %c3 = load i32, ptr %ptr1116 %c4 = zext i8 %c1 to i32117 %c5 = sext i16 %c2 to i32118 %c6 = add i32 %c4, %c5119 %c7 = sub i32 %c3, %c6120 store i32 %c7, ptr %ptr1121 ret void122 123; THUMB: ldrb124; THUMB: ldrh125; THUMB: and{{.*}}, #255126; THUMB: sxth127; THUMB: add128; THUMB: sub129; ARM: ldrb130; ARM: ldrh131; ARM: and{{.*}}, #255132; ARM: sxth133; ARM: add134; ARM: sub135}136 137; Check loads/stores with globals138@test4g = external global i32139 140define void @test4() {141 %a = load i32, ptr @test4g142 %b = add i32 %a, 1143 store i32 %b, ptr @test4g144 ret void145 146 147; Note that relocations are either movw/movt or constant pool148; loads. Different platforms will select different approaches.149 150; THUMB: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}151; THUMB: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}152; THUMB: ldr [[REG:r[0-9]+]], [r0]153; THUMB: ldr [[REG1:r[0-9]+]], [[[REG]]]154; THUMB: adds [[REG1]], #1155; THUMB: {{(movw r1, :lower16:L_test4g\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}156; THUMB: {{(movt r1, :upper16:L_test4g\$non_lazy_ptr)?}}157; THUMB: ldr [[REG2:r[0-9]+]], [r1]158; THUMB: str [[REG1]], [[[REG2]]]159 160; ARM-MACHO: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr r0, .LCPI)}}161; ARM-MACHO: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}162; ARM-MACHO: ldr [[REG:r[0-9]+]], [r0]163 164; ARM-ELF: movw [[REG:r[0-9]+]], :lower16:test4g165; ARM-ELF: movt [[REG]], :upper16:test4g166 167; ARM: ldr [[REG1:r[0-9]+]], [[[REG]]]168; ARM: add [[REG2:r[0-9]+]], [[REG1]], #1169 170; ARM-MACHO: {{(movw r1, :lower16:L_test4g\$non_lazy_ptr)|(ldr r0, .LCPI)}}171; ARM-MACHO: {{(movt r1, :upper16:L_test4g\$non_lazy_ptr)?}}172; ARM-MACHO: ldr [[REG3:r[0-9]+]], [r1]173 174; ARM-ELF: movw [[REG3:r[0-9]+]], :lower16:test4g175; ARM-ELF: movt [[REG3]], :upper16:test4g176 177; ARM: str [[REG2]], [[[REG3]]]178}179 180; ARM: @urem_fold181; THUMB: @urem_fold182; ARM: and r0, r0, #31183; THUMB: and r0, r0, #31184define i32 @urem_fold(i32 %a) nounwind {185 %rem = urem i32 %a, 32186 ret i32 %rem187}188 189define i32 @trap_intrinsic() noreturn nounwind {190entry:191; ARM: @trap_intrinsic192; THUMB: @trap_intrinsic193; ARM: trap194; THUMB: trap195 tail call void @llvm.trap( )196 unreachable197}198 199declare void @llvm.trap() nounwind200