463 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc -mtriple=armv7-eabi -mattr=-fpregs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ARM3; RUN: llc -mtriple=armv7-eabi -mattr=+vfp2 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-VFP4; RUN: llc -mtriple=thumbv7-apple-darwin -mattr=+neon,+thumb2 %s -o - | FileCheck %s --check-prefix=CHECK-NEON5 6define i32 @f1(i32 %a.s) {7; CHECK-LABEL: f1:8; CHECK: @ %bb.0: @ %entry9; CHECK-NEXT: mov r1, #310; CHECK-NEXT: cmp r0, #411; CHECK-NEXT: movweq r1, #212; CHECK-NEXT: mov r0, r113; CHECK-NEXT: bx lr14;15; CHECK-NEON-LABEL: f1:16; CHECK-NEON: @ %bb.0: @ %entry17; CHECK-NEON-NEXT: movs r1, #318; CHECK-NEON-NEXT: cmp r0, #419; CHECK-NEON-NEXT: it eq20; CHECK-NEON-NEXT: moveq r1, #221; CHECK-NEON-NEXT: mov r0, r122; CHECK-NEON-NEXT: bx lr23entry:24 %tmp = icmp eq i32 %a.s, 425 %tmp1.s = select i1 %tmp, i32 2, i32 326 ret i32 %tmp1.s27}28 29define i32 @f2(i32 %a.s) {30; CHECK-LABEL: f2:31; CHECK: @ %bb.0: @ %entry32; CHECK-NEXT: mov r1, #333; CHECK-NEXT: cmp r0, #434; CHECK-NEXT: movwgt r1, #235; CHECK-NEXT: mov r0, r136; CHECK-NEXT: bx lr37;38; CHECK-NEON-LABEL: f2:39; CHECK-NEON: @ %bb.0: @ %entry40; CHECK-NEON-NEXT: movs r1, #341; CHECK-NEON-NEXT: cmp r0, #442; CHECK-NEON-NEXT: it gt43; CHECK-NEON-NEXT: movgt r1, #244; CHECK-NEON-NEXT: mov r0, r145; CHECK-NEON-NEXT: bx lr46entry:47 %tmp = icmp sgt i32 %a.s, 448 %tmp1.s = select i1 %tmp, i32 2, i32 349 ret i32 %tmp1.s50}51 52define i32 @f3(i32 %a.s, i32 %b.s) {53; CHECK-LABEL: f3:54; CHECK: @ %bb.0: @ %entry55; CHECK-NEXT: mov r2, #356; CHECK-NEXT: cmp r0, r157; CHECK-NEXT: movwlt r2, #258; CHECK-NEXT: mov r0, r259; CHECK-NEXT: bx lr60;61; CHECK-NEON-LABEL: f3:62; CHECK-NEON: @ %bb.0: @ %entry63; CHECK-NEON-NEXT: movs r2, #364; CHECK-NEON-NEXT: cmp r0, r165; CHECK-NEON-NEXT: it lt66; CHECK-NEON-NEXT: movlt r2, #267; CHECK-NEON-NEXT: mov r0, r268; CHECK-NEON-NEXT: bx lr69entry:70 %tmp = icmp slt i32 %a.s, %b.s71 %tmp1.s = select i1 %tmp, i32 2, i32 372 ret i32 %tmp1.s73}74 75define i32 @f4(i32 %a.s, i32 %b.s) {76; CHECK-LABEL: f4:77; CHECK: @ %bb.0: @ %entry78; CHECK-NEXT: mov r2, #379; CHECK-NEXT: cmp r0, r180; CHECK-NEXT: movwle r2, #281; CHECK-NEXT: mov r0, r282; CHECK-NEXT: bx lr83;84; CHECK-NEON-LABEL: f4:85; CHECK-NEON: @ %bb.0: @ %entry86; CHECK-NEON-NEXT: movs r2, #387; CHECK-NEON-NEXT: cmp r0, r188; CHECK-NEON-NEXT: it le89; CHECK-NEON-NEXT: movle r2, #290; CHECK-NEON-NEXT: mov r0, r291; CHECK-NEON-NEXT: bx lr92entry:93 %tmp = icmp sle i32 %a.s, %b.s94 %tmp1.s = select i1 %tmp, i32 2, i32 395 ret i32 %tmp1.s96}97 98define i32 @f5(i32 %a.u, i32 %b.u) {99; CHECK-LABEL: f5:100; CHECK: @ %bb.0: @ %entry101; CHECK-NEXT: mov r2, #3102; CHECK-NEXT: cmp r0, r1103; CHECK-NEXT: movwls r2, #2104; CHECK-NEXT: mov r0, r2105; CHECK-NEXT: bx lr106;107; CHECK-NEON-LABEL: f5:108; CHECK-NEON: @ %bb.0: @ %entry109; CHECK-NEON-NEXT: movs r2, #3110; CHECK-NEON-NEXT: cmp r0, r1111; CHECK-NEON-NEXT: it ls112; CHECK-NEON-NEXT: movls r2, #2113; CHECK-NEON-NEXT: mov r0, r2114; CHECK-NEON-NEXT: bx lr115entry:116 %tmp = icmp ule i32 %a.u, %b.u117 %tmp1.s = select i1 %tmp, i32 2, i32 3118 ret i32 %tmp1.s119}120 121define i32 @f6(i32 %a.u, i32 %b.u) {122; CHECK-LABEL: f6:123; CHECK: @ %bb.0: @ %entry124; CHECK-NEXT: mov r2, #3125; CHECK-NEXT: cmp r0, r1126; CHECK-NEXT: movwhi r2, #2127; CHECK-NEXT: mov r0, r2128; CHECK-NEXT: bx lr129;130; CHECK-NEON-LABEL: f6:131; CHECK-NEON: @ %bb.0: @ %entry132; CHECK-NEON-NEXT: movs r2, #3133; CHECK-NEON-NEXT: cmp r0, r1134; CHECK-NEON-NEXT: it hi135; CHECK-NEON-NEXT: movhi r2, #2136; CHECK-NEON-NEXT: mov r0, r2137; CHECK-NEON-NEXT: bx lr138entry:139 %tmp = icmp ugt i32 %a.u, %b.u140 %tmp1.s = select i1 %tmp, i32 2, i32 3141 ret i32 %tmp1.s142}143 144define double @f7(double %a, double %b) {145; CHECK-ARM-LABEL: f7:146; CHECK-ARM: @ %bb.0:147; CHECK-ARM-NEXT: .save {r4, r5, r11, lr}148; CHECK-ARM-NEXT: push {r4, r5, r11, lr}149; CHECK-ARM-NEXT: mov r4, r3150; CHECK-ARM-NEXT: movw r3, #48758151; CHECK-ARM-NEXT: mov r5, r2152; CHECK-ARM-NEXT: movw r2, #14680153; CHECK-ARM-NEXT: movt r2, #51380154; CHECK-ARM-NEXT: movt r3, #16371155; CHECK-ARM-NEXT: bl __aeabi_dcmplt156; CHECK-ARM-NEXT: cmp r0, #0157; CHECK-ARM-NEXT: movwne r4, #0158; CHECK-ARM-NEXT: movwne r5, #0159; CHECK-ARM-NEXT: movtne r4, #49136160; CHECK-ARM-NEXT: mov r0, r5161; CHECK-ARM-NEXT: mov r1, r4162; CHECK-ARM-NEXT: pop {r4, r5, r11, pc}163;164; CHECK-VFP-LABEL: f7:165; CHECK-VFP: @ %bb.0:166; CHECK-VFP-NEXT: vldr d17, .LCPI6_0167; CHECK-VFP-NEXT: vmov d18, r0, r1168; CHECK-VFP-NEXT: vmov.f64 d16, #-1.000000e+00169; CHECK-VFP-NEXT: vcmp.f64 d18, d17170; CHECK-VFP-NEXT: vmrs APSR_nzcv, fpscr171; CHECK-VFP-NEXT: vmov d19, r2, r3172; CHECK-VFP-NEXT: vmovmi.f64 d19, d16173; CHECK-VFP-NEXT: vmov r0, r1, d19174; CHECK-VFP-NEXT: bx lr175; CHECK-VFP-NEXT: .p2align 3176; CHECK-VFP-NEXT: @ %bb.1:177; CHECK-VFP-NEXT: .LCPI6_0:178; CHECK-VFP-NEXT: .long 3367254360 @ double 1.234179; CHECK-VFP-NEXT: .long 1072938614180;181; CHECK-NEON-LABEL: f7:182; CHECK-NEON: @ %bb.0:183; CHECK-NEON-NEXT: vldr d17, LCPI6_0184; CHECK-NEON-NEXT: vmov d18, r0, r1185; CHECK-NEON-NEXT: vmov d19, r2, r3186; CHECK-NEON-NEXT: vcmp.f64 d18, d17187; CHECK-NEON-NEXT: vmov.f64 d16, #-1.000000e+00188; CHECK-NEON-NEXT: vmrs APSR_nzcv, fpscr189; CHECK-NEON-NEXT: it mi190; CHECK-NEON-NEXT: vmovmi.f64 d19, d16191; CHECK-NEON-NEXT: vmov r0, r1, d19192; CHECK-NEON-NEXT: bx lr193; CHECK-NEON-NEXT: .p2align 3194; CHECK-NEON-NEXT: @ %bb.1:195; CHECK-NEON-NEXT: .data_region196; CHECK-NEON-NEXT: LCPI6_0:197; CHECK-NEON-NEXT: .long 3367254360 @ double 1.234198; CHECK-NEON-NEXT: .long 1072938614199; CHECK-NEON-NEXT: .end_data_region200 %tmp = fcmp olt double %a, 1.234e+00201 %tmp1 = select i1 %tmp, double -1.000e+00, double %b202 ret double %tmp1203}204 205; <rdar://problem/7260094>206;207; We used to generate really horrible code for this function. The main cause was208; a lack of a custom lowering routine for an ISD::SELECT. This would result in209; two "it" blocks in the code: one for the "icmp" and another to move the index210; into the constant pool based on the value of the "icmp". If we have one "it"211; block generated, odds are good that we have close to the ideal code for this.212define arm_apcscc float @f8(i32 %a) nounwind {213; CHECK-ARM-LABEL: f8:214; CHECK-ARM: @ %bb.0:215; CHECK-ARM-NEXT: movw r1, #29905216; CHECK-ARM-NEXT: movw r2, #1123217; CHECK-ARM-NEXT: movt r1, #16408218; CHECK-ARM-NEXT: cmp r0, r2219; CHECK-ARM-NEXT: movweq r1, #62390220; CHECK-ARM-NEXT: movteq r1, #16285221; CHECK-ARM-NEXT: mov r0, r1222; CHECK-ARM-NEXT: bx lr223;224; CHECK-VFP-LABEL: f8:225; CHECK-VFP: @ %bb.0:226; CHECK-VFP-NEXT: movw r2, #1123227; CHECK-VFP-NEXT: adr r1, .LCPI7_0228; CHECK-VFP-NEXT: cmp r0, r2229; CHECK-VFP-NEXT: addeq r1, r1, #4230; CHECK-VFP-NEXT: ldr r0, [r1]231; CHECK-VFP-NEXT: bx lr232; CHECK-VFP-NEXT: .p2align 2233; CHECK-VFP-NEXT: @ %bb.1:234; CHECK-VFP-NEXT: .LCPI7_0:235; CHECK-VFP-NEXT: .long 0x401874d1 @ float 2.38212991236; CHECK-VFP-NEXT: .long 0x3f9df3b6 @ float 1.23399997237;238; CHECK-NEON-LABEL: f8:239; CHECK-NEON: @ %bb.0:240; CHECK-NEON-NEXT: adr r1, LCPI7_0241; CHECK-NEON-NEXT: movw r2, #1123242; CHECK-NEON-NEXT: cmp r0, r2243; CHECK-NEON-NEXT: it eq244; CHECK-NEON-NEXT: addeq r1, #4245; CHECK-NEON-NEXT: ldr r0, [r1]246; CHECK-NEON-NEXT: bx lr247; CHECK-NEON-NEXT: .p2align 2248; CHECK-NEON-NEXT: @ %bb.1:249; CHECK-NEON-NEXT: .data_region250; CHECK-NEON-NEXT: LCPI7_0:251; CHECK-NEON-NEXT: .long 0x401874d1 @ float 2.38212991252; CHECK-NEON-NEXT: .long 0x3f9df3b6 @ float 1.23399997253; CHECK-NEON-NEXT: .end_data_region254 %tmp = icmp eq i32 %a, 1123255 %tmp1 = select i1 %tmp, float 0x3FF3BE76C0000000, float 0x40030E9A20000000256 ret float %tmp1257}258 259; <rdar://problem/9049552>260; Glue values can only have a single use, but the following test exposed a261; case where a SELECT was lowered with 2 uses of a comparison, causing the262; scheduler to assert.263declare ptr @objc_msgSend(ptr, ptr, ...)264define void @f9() optsize {265; CHECK-LABEL: f9:266; CHECK: @ %bb.0: @ %entry267; CHECK-NEXT: .save {r11, lr}268; CHECK-NEXT: push {r11, lr}269; CHECK-NEXT: .pad #8270; CHECK-NEXT: sub sp, sp, #8271; CHECK-NEXT: movw r2, #0272; CHECK-NEXT: movw r3, #0273; CHECK-NEXT: mov r1, #1065353216274; CHECK-NEXT: mov r0, #0275; CHECK-NEXT: movt r2, #16672276; CHECK-NEXT: movt r3, #32704277; CHECK-NEXT: strd r0, r1, [sp]278; CHECK-NEXT: bl objc_msgSend279; CHECK-NEXT: add sp, sp, #8280; CHECK-NEXT: pop {r11, pc}281;282; CHECK-NEON-LABEL: f9:283; CHECK-NEON: @ %bb.0: @ %entry284; CHECK-NEON-NEXT: str lr, [sp, #-4]!285; CHECK-NEON-NEXT: sub sp, #8286; CHECK-NEON-NEXT: movs r2, #0287; CHECK-NEON-NEXT: movs r3, #0288; CHECK-NEON-NEXT: mov.w r0, #1065353216289; CHECK-NEON-NEXT: movs r1, #0290; CHECK-NEON-NEXT: movt r2, #16672291; CHECK-NEON-NEXT: movt r3, #32704292; CHECK-NEON-NEXT: strd r1, r0, [sp]293; CHECK-NEON-NEXT: bl _objc_msgSend294; CHECK-NEON-NEXT: add sp, #8295; CHECK-NEON-NEXT: ldr lr, [sp], #4296; CHECK-NEON-NEXT: bx lr297entry:298 %cmp = icmp eq ptr undef, inttoptr (i32 4 to ptr)299 %conv191 = select i1 %cmp, float -3.000000e+00, float 0.000000e+00300 %conv195 = select i1 %cmp, double -1.000000e+00, double 0.000000e+00301 %add = fadd double %conv195, 1.100000e+01302 %conv196 = fptrunc double %add to float303 %add201 = fadd float undef, %conv191304 %tmp484 = bitcast float %conv196 to i32305 %tmp478 = bitcast float %add201 to i32306 %tmp490 = insertvalue [2 x i32] undef, i32 %tmp484, 0307 %tmp493 = insertvalue [2 x i32] %tmp490, i32 %tmp478, 1308 call void @objc_msgSend(ptr undef, ptr undef, [2 x i32] %tmp493, i32 0, float 1.000000e+00) optsize309 ret void310}311 312define float @f10(i32 %a, i32 %b) nounwind uwtable readnone ssp {313; CHECK-ARM-LABEL: f10:314; CHECK-ARM: @ %bb.0:315; CHECK-ARM-NEXT: mov r2, #0316; CHECK-ARM-NEXT: cmp r0, r1317; CHECK-ARM-NEXT: moveq r2, #1065353216318; CHECK-ARM-NEXT: mov r0, r2319; CHECK-ARM-NEXT: bx lr320;321; CHECK-VFP-LABEL: f10:322; CHECK-VFP: @ %bb.0:323; CHECK-VFP-NEXT: vmov.f32 s0, #1.000000e+00324; CHECK-VFP-NEXT: vldr s2, .LCPI9_0325; CHECK-VFP-NEXT: cmp r0, r1326; CHECK-VFP-NEXT: vmoveq.f32 s2, s0327; CHECK-VFP-NEXT: vmov r0, s2328; CHECK-VFP-NEXT: bx lr329; CHECK-VFP-NEXT: .p2align 2330; CHECK-VFP-NEXT: @ %bb.1:331; CHECK-VFP-NEXT: .LCPI9_0:332; CHECK-VFP-NEXT: .long 0x00000000 @ float 0333;334; CHECK-NEON-LABEL: f10:335; CHECK-NEON: @ %bb.0:336; CHECK-NEON-NEXT: vldr s2, LCPI9_0337; CHECK-NEON-NEXT: vmov.f32 s0, #1.000000e+00338; CHECK-NEON-NEXT: cmp r0, r1339; CHECK-NEON-NEXT: it eq340; CHECK-NEON-NEXT: vmoveq.f32 s2, s0341; CHECK-NEON-NEXT: vmov r0, s2342; CHECK-NEON-NEXT: bx lr343; CHECK-NEON-NEXT: .p2align 2344; CHECK-NEON-NEXT: @ %bb.1:345; CHECK-NEON-NEXT: .data_region346; CHECK-NEON-NEXT: LCPI9_0:347; CHECK-NEON-NEXT: .long 0x00000000 @ float 0348; CHECK-NEON-NEXT: .end_data_region349 %1 = icmp eq i32 %a, %b350 %2 = zext i1 %1 to i32351 %3 = sitofp i32 %2 to float352 ret float %3353}354 355define float @f11(i32 %a, i32 %b) nounwind uwtable readnone ssp {356; CHECK-ARM-LABEL: f11:357; CHECK-ARM: @ %bb.0:358; CHECK-ARM-NEXT: mov r2, #0359; CHECK-ARM-NEXT: cmp r0, r1360; CHECK-ARM-NEXT: movweq r2, #0361; CHECK-ARM-NEXT: movteq r2, #49024362; CHECK-ARM-NEXT: mov r0, r2363; CHECK-ARM-NEXT: bx lr364;365; CHECK-VFP-LABEL: f11:366; CHECK-VFP: @ %bb.0:367; CHECK-VFP-NEXT: vmov.f32 s0, #-1.000000e+00368; CHECK-VFP-NEXT: vldr s2, .LCPI10_0369; CHECK-VFP-NEXT: cmp r0, r1370; CHECK-VFP-NEXT: vmoveq.f32 s2, s0371; CHECK-VFP-NEXT: vmov r0, s2372; CHECK-VFP-NEXT: bx lr373; CHECK-VFP-NEXT: .p2align 2374; CHECK-VFP-NEXT: @ %bb.1:375; CHECK-VFP-NEXT: .LCPI10_0:376; CHECK-VFP-NEXT: .long 0x00000000 @ float 0377;378; CHECK-NEON-LABEL: f11:379; CHECK-NEON: @ %bb.0:380; CHECK-NEON-NEXT: vldr s2, LCPI10_0381; CHECK-NEON-NEXT: vmov.f32 s0, #-1.000000e+00382; CHECK-NEON-NEXT: cmp r0, r1383; CHECK-NEON-NEXT: it eq384; CHECK-NEON-NEXT: vmoveq.f32 s2, s0385; CHECK-NEON-NEXT: vmov r0, s2386; CHECK-NEON-NEXT: bx lr387; CHECK-NEON-NEXT: .p2align 2388; CHECK-NEON-NEXT: @ %bb.1:389; CHECK-NEON-NEXT: .data_region390; CHECK-NEON-NEXT: LCPI10_0:391; CHECK-NEON-NEXT: .long 0x00000000 @ float 0392; CHECK-NEON-NEXT: .end_data_region393 %1 = icmp eq i32 %a, %b394 %2 = sitofp i1 %1 to float395 ret float %2396}397 398define float @f12(i32 %a, i32 %b) nounwind uwtable readnone ssp {399; CHECK-ARM-LABEL: f12:400; CHECK-ARM: @ %bb.0:401; CHECK-ARM-NEXT: mov r2, #0402; CHECK-ARM-NEXT: cmp r0, r1403; CHECK-ARM-NEXT: moveq r2, #1065353216404; CHECK-ARM-NEXT: mov r0, r2405; CHECK-ARM-NEXT: bx lr406;407; CHECK-VFP-LABEL: f12:408; CHECK-VFP: @ %bb.0:409; CHECK-VFP-NEXT: vmov.f32 s0, #1.000000e+00410; CHECK-VFP-NEXT: vldr s2, .LCPI11_0411; CHECK-VFP-NEXT: cmp r0, r1412; CHECK-VFP-NEXT: vmoveq.f32 s2, s0413; CHECK-VFP-NEXT: vmov r0, s2414; CHECK-VFP-NEXT: bx lr415; CHECK-VFP-NEXT: .p2align 2416; CHECK-VFP-NEXT: @ %bb.1:417; CHECK-VFP-NEXT: .LCPI11_0:418; CHECK-VFP-NEXT: .long 0x00000000 @ float 0419;420; CHECK-NEON-LABEL: f12:421; CHECK-NEON: @ %bb.0:422; CHECK-NEON-NEXT: vldr s2, LCPI11_0423; CHECK-NEON-NEXT: vmov.f32 s0, #1.000000e+00424; CHECK-NEON-NEXT: cmp r0, r1425; CHECK-NEON-NEXT: it eq426; CHECK-NEON-NEXT: vmoveq.f32 s2, s0427; CHECK-NEON-NEXT: vmov r0, s2428; CHECK-NEON-NEXT: bx lr429; CHECK-NEON-NEXT: .p2align 2430; CHECK-NEON-NEXT: @ %bb.1:431; CHECK-NEON-NEXT: .data_region432; CHECK-NEON-NEXT: LCPI11_0:433; CHECK-NEON-NEXT: .long 0x00000000 @ float 0434; CHECK-NEON-NEXT: .end_data_region435 %1 = icmp eq i32 %a, %b436 %2 = uitofp i1 %1 to float437 ret float %2438}439 440define i1 @test_overflow_recombine(i32 %in1, i32 %in2) {441; CHECK-LABEL: test_overflow_recombine:442; CHECK: @ %bb.0:443; CHECK-NEXT: mul r2, r0, r1444; CHECK-NEXT: smmul r0, r0, r1445; CHECK-NEXT: subs r0, r0, r2, asr #31446; CHECK-NEXT: movwne r0, #1447; CHECK-NEXT: bx lr448;449; CHECK-NEON-LABEL: test_overflow_recombine:450; CHECK-NEON: @ %bb.0:451; CHECK-NEON-NEXT: mul r2, r0, r1452; CHECK-NEON-NEXT: smmul r0, r0, r1453; CHECK-NEON-NEXT: subs.w r0, r0, r2, asr #31454; CHECK-NEON-NEXT: it ne455; CHECK-NEON-NEXT: movne r0, #1456; CHECK-NEON-NEXT: bx lr457 %prod = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %in1, i32 %in2)458 %overflow = extractvalue { i32, i1 } %prod, 1459 ret i1 %overflow460}461 462declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)463