464 lines · plain
1; RUN: llc -mtriple arm-unknown -mattr=+vfp2,+v6 -global-isel %s -o - | FileCheck %s2 3define void @test_void_return() {4; CHECK-LABEL: test_void_return:5; CHECK: bx lr6entry:7 ret void8}9 10define i32 @test_constant_return_i32() {11; CHECK-LABEL: test_constant_return_i32:12; CHECK: mov r0, #4213; CHECK: bx lr14entry:15 ret i32 4216}17 18define zeroext i1 @test_zext_i1(i1 %x) {19; CHECK-LABEL: test_zext_i120; CHECK: and r0, r0, #121; CHECK: bx lr22entry:23 ret i1 %x24}25 26define signext i1 @test_sext_i1(i1 %x) {27; CHECK-LABEL: test_sext_i128; CHECK: mov r1, #3129; CHECK: lsl r0, r0, r130; CHECK: asr r0, r0, r131; CHECK: bx lr32entry:33 ret i1 %x34}35 36define zeroext i8 @test_ext_i8(i8 %x) {37; CHECK-LABEL: test_ext_i8:38; CHECK: uxtb r0, r039; CHECK: bx lr40 41entry:42 ret i8 %x43}44 45define signext i16 @test_ext_i16(i16 %x) {46; CHECK-LABEL: test_ext_i16:47; CHECK: mov r1, #1648; CHECK: lsl r0, r0, r149; CHECK: asr r0, r0, r150; CHECK: bx lr51entry:52 ret i16 %x53}54 55define void @test_trunc_i32_i16(i32 %v, ptr %p) {56; CHECK-LABEL: test_trunc_i32_i16:57; The trunc doesn't result in any instructions, but we58; expect the store to be explicitly 16-bit.59; CHECK: strh r0, [r1]60; CHECK: bx lr61entry:62 %v16 = trunc i32 %v to i1663 store i16 %v16, ptr %p64 ret void65}66 67define void @test_trunc_i32_i8(i32 %v, ptr %p) {68; CHECK-LABEL: test_trunc_i32_i8:69; The trunc doesn't result in any instructions, but we70; expect the store to be explicitly 8-bit.71; CHECK: strb r0, [r1]72; CHECK: bx lr73entry:74 %v8 = trunc i32 %v to i875 store i8 %v8, ptr %p76 ret void77}78 79define i8 @test_add_i8(i8 %x, i8 %y) {80; CHECK-LABEL: test_add_i8:81; CHECK: add r0, r0, r182; CHECK: bx lr83entry:84 %sum = add i8 %x, %y85 ret i8 %sum86}87 88define i16 @test_add_i16(i16 %x, i16 %y) {89; CHECK-LABEL: test_add_i16:90; CHECK: add r0, r0, r191; CHECK: bx lr92entry:93 %sum = add i16 %x, %y94 ret i16 %sum95}96 97define i32 @test_add_i32(i32 %x, i32 %y) {98; CHECK-LABEL: test_add_i32:99; CHECK: add r0, r0, r1100; CHECK: bx lr101entry:102 %sum = add i32 %x, %y103 ret i32 %sum104}105 106define i8 @test_sub_i8(i8 %x, i8 %y) {107; CHECK-LABEL: test_sub_i8:108; CHECK: sub r0, r0, r1109; CHECK: bx lr110entry:111 %sum = sub i8 %x, %y112 ret i8 %sum113}114 115define i16 @test_sub_i16(i16 %x, i16 %y) {116; CHECK-LABEL: test_sub_i16:117; CHECK: sub r0, r0, r1118; CHECK: bx lr119entry:120 %sum = sub i16 %x, %y121 ret i16 %sum122}123 124define i32 @test_sub_i32(i32 %x, i32 %y) {125; CHECK-LABEL: test_sub_i32:126; CHECK: sub r0, r0, r1127; CHECK: bx lr128entry:129 %sum = sub i32 %x, %y130 ret i32 %sum131}132 133define i8 @test_mul_i8(i8 %x, i8 %y) {134; CHECK-LABEL: test_mul_i8:135; CHECK: mul r0, r0, r1136; CHECK: bx lr137entry:138 %sum = mul i8 %x, %y139 ret i8 %sum140}141 142define i16 @test_mul_i16(i16 %x, i16 %y) {143; CHECK-LABEL: test_mul_i16:144; CHECK: mul r0, r0, r1145; CHECK: bx lr146entry:147 %sum = mul i16 %x, %y148 ret i16 %sum149}150 151define i32 @test_mul_i32(i32 %x, i32 %y) {152; CHECK-LABEL: test_mul_i32:153; CHECK: mul r0, r0, r1154; CHECK: bx lr155entry:156 %sum = mul i32 %x, %y157 ret i32 %sum158}159 160define i8 @test_and_i8(i8 %x, i8 %y) {161; CHECK-LABEL: test_and_i8:162; CHECK: and r0, r0, r1163; CHECK: bx lr164entry:165 %sum = and i8 %x, %y166 ret i8 %sum167}168 169define i16 @test_and_i16(i16 %x, i16 %y) {170; CHECK-LABEL: test_and_i16:171; CHECK: and r0, r0, r1172; CHECK: bx lr173entry:174 %sum = and i16 %x, %y175 ret i16 %sum176}177 178define i32 @test_and_i32(i32 %x, i32 %y) {179; CHECK-LABEL: test_and_i32:180; CHECK: and r0, r0, r1181; CHECK: bx lr182entry:183 %sum = and i32 %x, %y184 ret i32 %sum185}186 187define i8 @test_or_i8(i8 %x, i8 %y) {188; CHECK-LABEL: test_or_i8:189; CHECK: orr r0, r0, r1190; CHECK: bx lr191entry:192 %sum = or i8 %x, %y193 ret i8 %sum194}195 196define i16 @test_or_i16(i16 %x, i16 %y) {197; CHECK-LABEL: test_or_i16:198; CHECK: orr r0, r0, r1199; CHECK: bx lr200entry:201 %sum = or i16 %x, %y202 ret i16 %sum203}204 205define i32 @test_or_i32(i32 %x, i32 %y) {206; CHECK-LABEL: test_or_i32:207; CHECK: orr r0, r0, r1208; CHECK: bx lr209entry:210 %sum = or i32 %x, %y211 ret i32 %sum212}213 214define i8 @test_xor_i8(i8 %x, i8 %y) {215; CHECK-LABEL: test_xor_i8:216; CHECK: eor r0, r0, r1217; CHECK: bx lr218entry:219 %sum = xor i8 %x, %y220 ret i8 %sum221}222 223define i16 @test_xor_i16(i16 %x, i16 %y) {224; CHECK-LABEL: test_xor_i16:225; CHECK: eor r0, r0, r1226; CHECK: bx lr227entry:228 %sum = xor i16 %x, %y229 ret i16 %sum230}231 232define i32 @test_xor_i32(i32 %x, i32 %y) {233; CHECK-LABEL: test_xor_i32:234; CHECK: eor r0, r0, r1235; CHECK: bx lr236entry:237 %sum = xor i32 %x, %y238 ret i32 %sum239}240 241define i32 @test_stack_args_i32(i32 %p0, i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) {242; CHECK-LABEL: test_stack_args_i32:243; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4244; CHECK: ldr [[P5:r[0-9]+]], {{.*}}[[P5ADDR]]245; CHECK: add r0, r2, [[P5]]246; CHECK: bx lr247entry:248 %sum = add i32 %p2, %p5249 ret i32 %sum250}251 252define i16 @test_stack_args_mixed(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 %p4, i16 %p5) {253; CHECK-LABEL: test_stack_args_mixed:254; CHECK: add [[P5ADDR:r[0-9]+]], sp, #4255; CHECK: ldr [[P5:r[0-9]+]], {{.*}}[[P5ADDR]]256; CHECK: add r0, r1, [[P5]]257; CHECK: bx lr258entry:259 %sum = add i16 %p1, %p5260 ret i16 %sum261}262 263define i16 @test_stack_args_zeroext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i16 zeroext %p4) {264; CHECK-LABEL: test_stack_args_zeroext:265; CHECK: mov [[P4ADDR:r[0-9]+]], sp266; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]267; CHECK: add r0, r1, [[P4]]268; CHECK: bx lr269entry:270 %sum = add i16 %p1, %p4271 ret i16 %sum272}273 274define i8 @test_stack_args_signext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 signext %p4) {275; CHECK-LABEL: test_stack_args_signext:276; CHECK: mov [[P4ADDR:r[0-9]+]], sp277; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]278; CHECK: add r0, r2, [[P4]]279; CHECK: bx lr280entry:281 %sum = add i8 %p2, %p4282 ret i8 %sum283}284 285define i8 @test_stack_args_noext(i32 %p0, i16 %p1, i8 %p2, i1 %p3, i8 %p4) {286; CHECK-LABEL: test_stack_args_noext:287; CHECK: mov [[P4ADDR:r[0-9]+]], sp288; CHECK: ldr [[P4:r[0-9]+]], {{.*}}[[P4ADDR]]289; CHECK: add r0, r2, [[P4]]290; CHECK: bx lr291entry:292 %sum = add i8 %p2, %p4293 ret i8 %sum294}295 296define i32 @test_ptr_arg_in_reg(ptr %p) {297; CHECK-LABEL: test_ptr_arg_in_reg:298; CHECK: ldr r0, [r0]299; CHECK: bx lr300entry:301 %v = load i32, ptr %p302 ret i32 %v303}304 305define i32 @test_ptr_arg_on_stack(i32 %f0, i32 %f1, i32 %f2, i32 %f3, ptr %p) {306; CHECK-LABEL: test_ptr_arg_on_stack:307; CHECK: mov r0, sp308; CHECK: ldr r0, [r0]309; CHECK: ldr r0, [r0]310; CHECK: bx lr311entry:312 %v = load i32, ptr %p313 ret i32 %v314}315 316define ptr @test_ptr_ret(ptr %p) {317; CHECK-LABEL: test_ptr_ret:318; CHECK: ldr r0, [r0]319; CHECK: bx lr320entry:321 %v = load ptr, ptr %p322 ret ptr %v323}324 325define arm_aapcs_vfpcc float @test_float_hard(float %f0, float %f1) {326; CHECK-LABEL: test_float_hard:327; CHECK: vadd.f32 s0, s0, s1328; CHECK: bx lr329entry:330 %v = fadd float %f0, %f1331 ret float %v332}333 334define arm_aapcscc float @test_float_softfp(float %f0, float %f1) {335; CHECK-LABEL: test_float_softfp:336; CHECK-DAG: vmov [[F0:s[0-9]+]], r0337; CHECK-DAG: vmov [[F1:s[0-9]+]], r1338; CHECK: vadd.f32 [[FV:s[0-9]+]], [[F0]], [[F1]]339; CHECK: vmov r0, [[FV]]340; CHECK: bx lr341entry:342 %v = fadd float %f0, %f1343 ret float %v344}345 346define arm_aapcs_vfpcc double @test_double_hard(double %f0, double %f1) {347; CHECK-LABEL: test_double_hard:348; CHECK: vadd.f64 d0, d0, d1349; CHECK: bx lr350entry:351 %v = fadd double %f0, %f1352 ret double %v353}354 355define arm_aapcscc double @test_double_softfp(double %f0, double %f1) {356; CHECK-LABEL: test_double_softfp:357; CHECK-DAG: vmov [[F0:d[0-9]+]], r0, r1358; CHECK-DAG: vmov [[F1:d[0-9]+]], r2, r3359; CHECK: vadd.f64 [[FV:d[0-9]+]], [[F0]], [[F1]]360; CHECK: vmov r0, r1, [[FV]]361; CHECK: bx lr362entry:363 %v = fadd double %f0, %f1364 ret double %v365}366 367define arm_aapcscc i32 @test_cmp_i32_eq(i32 %a, i32 %b) {368; CHECK-LABEL: test_cmp_i32_eq:369; CHECK: mov [[V:r[0-9]+]], #0370; CHECK: cmp r0, r1371; CHECK: moveq [[V]], #1372; CHECK: and r0, [[V]], #1373; CHECK: bx lr374entry:375 %v = icmp eq i32 %a, %b376 %r = zext i1 %v to i32377 ret i32 %r378}379 380define arm_aapcscc i32 @test_cmp_ptr_neq(ptr %a, ptr %b) {381; CHECK-LABEL: test_cmp_ptr_neq:382; CHECK: mov [[V:r[0-9]+]], #0383; CHECK: cmp r0, r1384; CHECK: movne [[V]], #1385; CHECK: and r0, [[V]], #1386; CHECK: bx lr387entry:388 %v = icmp ne ptr %a, %b389 %r = zext i1 %v to i32390 ret i32 %r391}392 393define arm_aapcscc i32 @test_cmp_i16_slt(i16 %a, i16 %b) {394; CHECK-LABEL: test_cmp_i16_slt:395; CHECK-DAG: mov [[V:r[0-9]+]], #0396; CHECK: cmp r0, r1397; CHECK: movlt [[V]], #1398; CHECK: and r0, [[V]], #1399; CHECK: bx lr400entry:401 %v = icmp slt i16 %a, %b402 %r = zext i1 %v to i32403 ret i32 %r404}405 406define arm_aapcscc i32 @test_select_i32(i32 %a, i32 %b, i1 %cond) {407; CHECK-LABEL: test_select_i32408; CHECK: tst r2, #1409; CHECK: moveq r0, r1410; CHECK: bx lr411entry:412 %r = select i1 %cond, i32 %a, i32 %b413 ret i32 %r414}415 416define arm_aapcscc ptr @test_select_ptr(ptr %a, ptr %b, i1 %cond) {417; CHECK-LABEL: test_select_ptr418; CHECK: tst r2, #1419; CHECK: moveq r0, r1420; CHECK: bx lr421entry:422 %r = select i1 %cond, ptr %a, ptr %b423 ret ptr %r424}425 426define arm_aapcscc void @test_br() {427; CHECK-LABEL: test_br428; CHECK: [[LABEL:.L[[:alnum:]_]+]]:429; CHECK: b [[LABEL]]430entry:431 br label %infinite432 433infinite:434 br label %infinite435}436 437declare arm_aapcscc void @brcond1()438declare arm_aapcscc void @brcond2()439 440define arm_aapcscc void @test_brcond(i32 %n) {441; CHECK-LABEL: test_brcond442; CHECK: cmp r0443; CHECK-NEXT: movgt [[RCMP:r[0-9]+]], #1444; CHECK: tst [[RCMP]], #1445; CHECK-NEXT: beq [[FALSE:.L[[:alnum:]_]+]]446; CHECK: bl brcond1447; CHECK: [[FALSE]]:448; CHECK: bl brcond2449entry:450 %cmp = icmp sgt i32 %n, 0451 br i1 %cmp, label %if.true, label %if.false452 453if.true:454 call arm_aapcscc void @brcond1()455 br label %if.end456 457if.false:458 call arm_aapcscc void @brcond2()459 br label %if.end460 461if.end:462 ret void463}464