436 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- -mattr=sse2 | FileCheck %s --check-prefixes=SSE23; RUN: llc < %s -mtriple=x86_64-- -mattr=avx | FileCheck %s --check-prefixes=AVX,AVX14; RUN: llc < %s -mtriple=x86_64-- -mattr=avx512f | FileCheck %s --check-prefixes=AVX,AVX5125 6define i1 @olt_ole_and_f32(float %w, float %x, float %y, float %z) {7; SSE2-LABEL: olt_ole_and_f32:8; SSE2: # %bb.0:9; SSE2-NEXT: cmpless %xmm3, %xmm210; SSE2-NEXT: cmpltss %xmm1, %xmm011; SSE2-NEXT: andps %xmm2, %xmm012; SSE2-NEXT: movd %xmm0, %eax13; SSE2-NEXT: # kill: def $al killed $al killed $eax14; SSE2-NEXT: retq15;16; AVX1-LABEL: olt_ole_and_f32:17; AVX1: # %bb.0:18; AVX1-NEXT: vcmpless %xmm3, %xmm2, %xmm219; AVX1-NEXT: vcmpltss %xmm1, %xmm0, %xmm020; AVX1-NEXT: vandps %xmm2, %xmm0, %xmm021; AVX1-NEXT: vmovd %xmm0, %eax22; AVX1-NEXT: # kill: def $al killed $al killed $eax23; AVX1-NEXT: retq24;25; AVX512-LABEL: olt_ole_and_f32:26; AVX512: # %bb.0:27; AVX512-NEXT: vcmpless %xmm3, %xmm2, %k028; AVX512-NEXT: vcmpltss %xmm1, %xmm0, %k129; AVX512-NEXT: kandw %k0, %k1, %k030; AVX512-NEXT: kmovw %k0, %eax31; AVX512-NEXT: # kill: def $al killed $al killed $eax32; AVX512-NEXT: retq33 %f1 = fcmp olt float %w, %x34 %f2 = fcmp ole float %y, %z35 %r = and i1 %f1, %f236 ret i1 %r37}38 39define i1 @oge_oeq_or_f32(float %w, float %x, float %y, float %z) {40; SSE2-LABEL: oge_oeq_or_f32:41; SSE2: # %bb.0:42; SSE2-NEXT: cmpeqss %xmm3, %xmm243; SSE2-NEXT: cmpless %xmm0, %xmm144; SSE2-NEXT: orps %xmm2, %xmm145; SSE2-NEXT: movd %xmm1, %eax46; SSE2-NEXT: # kill: def $al killed $al killed $eax47; SSE2-NEXT: retq48;49; AVX1-LABEL: oge_oeq_or_f32:50; AVX1: # %bb.0:51; AVX1-NEXT: vcmpeqss %xmm3, %xmm2, %xmm252; AVX1-NEXT: vcmpless %xmm0, %xmm1, %xmm053; AVX1-NEXT: vorps %xmm2, %xmm0, %xmm054; AVX1-NEXT: vmovd %xmm0, %eax55; AVX1-NEXT: # kill: def $al killed $al killed $eax56; AVX1-NEXT: retq57;58; AVX512-LABEL: oge_oeq_or_f32:59; AVX512: # %bb.0:60; AVX512-NEXT: vcmpeqss %xmm3, %xmm2, %k061; AVX512-NEXT: vcmpless %xmm0, %xmm1, %k162; AVX512-NEXT: korw %k0, %k1, %k063; AVX512-NEXT: kmovw %k0, %eax64; AVX512-NEXT: # kill: def $al killed $al killed $eax65; AVX512-NEXT: retq66 %f1 = fcmp oge float %w, %x67 %f2 = fcmp oeq float %y, %z68 %r = or i1 %f1, %f269 ret i1 %r70}71 72define i1 @ord_one_xor_f32(float %w, float %x, float %y, float %z) {73; SSE2-LABEL: ord_one_xor_f32:74; SSE2: # %bb.0:75; SSE2-NEXT: ucomiss %xmm1, %xmm076; SSE2-NEXT: setnp %cl77; SSE2-NEXT: ucomiss %xmm3, %xmm278; SSE2-NEXT: setne %al79; SSE2-NEXT: xorb %cl, %al80; SSE2-NEXT: retq81;82; AVX1-LABEL: ord_one_xor_f32:83; AVX1: # %bb.0:84; AVX1-NEXT: vcmpneq_oqss %xmm3, %xmm2, %xmm285; AVX1-NEXT: vcmpordss %xmm1, %xmm0, %xmm086; AVX1-NEXT: vxorps %xmm2, %xmm0, %xmm087; AVX1-NEXT: vmovd %xmm0, %eax88; AVX1-NEXT: # kill: def $al killed $al killed $eax89; AVX1-NEXT: retq90;91; AVX512-LABEL: ord_one_xor_f32:92; AVX512: # %bb.0:93; AVX512-NEXT: vcmpneq_oqss %xmm3, %xmm2, %k094; AVX512-NEXT: vcmpordss %xmm1, %xmm0, %k195; AVX512-NEXT: kxorw %k0, %k1, %k096; AVX512-NEXT: kmovw %k0, %eax97; AVX512-NEXT: # kill: def $al killed $al killed $eax98; AVX512-NEXT: retq99 %f1 = fcmp ord float %w, %x100 %f2 = fcmp one float %y, %z101 %r = xor i1 %f1, %f2102 ret i1 %r103}104 105; PR51068106define i1 @une_oeq_xor_f32(float %w, float %x, float %y, float %z) {107; SSE2-LABEL: une_oeq_xor_f32:108; SSE2: # %bb.0:109; SSE2-NEXT: cmpeqss %xmm3, %xmm2110; SSE2-NEXT: cmpneqss %xmm1, %xmm0111; SSE2-NEXT: xorps %xmm2, %xmm0112; SSE2-NEXT: movd %xmm0, %eax113; SSE2-NEXT: # kill: def $al killed $al killed $eax114; SSE2-NEXT: retq115;116; AVX1-LABEL: une_oeq_xor_f32:117; AVX1: # %bb.0:118; AVX1-NEXT: vcmpeqss %xmm3, %xmm2, %xmm2119; AVX1-NEXT: vcmpneqss %xmm1, %xmm0, %xmm0120; AVX1-NEXT: vxorps %xmm2, %xmm0, %xmm0121; AVX1-NEXT: vmovd %xmm0, %eax122; AVX1-NEXT: # kill: def $al killed $al killed $eax123; AVX1-NEXT: retq124;125; AVX512-LABEL: une_oeq_xor_f32:126; AVX512: # %bb.0:127; AVX512-NEXT: vcmpeqss %xmm3, %xmm2, %k0128; AVX512-NEXT: vcmpneqss %xmm1, %xmm0, %k1129; AVX512-NEXT: kxorw %k0, %k1, %k0130; AVX512-NEXT: kmovw %k0, %eax131; AVX512-NEXT: # kill: def $al killed $al killed $eax132; AVX512-NEXT: retq133 %f1 = fcmp une float %w, %x134 %f2 = fcmp oeq float %y, %z135 %r = xor i1 %f1, %f2136 ret i1 %r137}138 139define i1 @une_ugt_and_f64(double %w, double %x, double %y, double %z) {140; SSE2-LABEL: une_ugt_and_f64:141; SSE2: # %bb.0:142; SSE2-NEXT: cmpnlesd %xmm3, %xmm2143; SSE2-NEXT: cmpneqsd %xmm1, %xmm0144; SSE2-NEXT: andpd %xmm2, %xmm0145; SSE2-NEXT: movd %xmm0, %eax146; SSE2-NEXT: # kill: def $al killed $al killed $eax147; SSE2-NEXT: retq148;149; AVX1-LABEL: une_ugt_and_f64:150; AVX1: # %bb.0:151; AVX1-NEXT: vcmpnlesd %xmm3, %xmm2, %xmm2152; AVX1-NEXT: vcmpneqsd %xmm1, %xmm0, %xmm0153; AVX1-NEXT: vandpd %xmm2, %xmm0, %xmm0154; AVX1-NEXT: vmovd %xmm0, %eax155; AVX1-NEXT: # kill: def $al killed $al killed $eax156; AVX1-NEXT: retq157;158; AVX512-LABEL: une_ugt_and_f64:159; AVX512: # %bb.0:160; AVX512-NEXT: vcmpnlesd %xmm3, %xmm2, %k0161; AVX512-NEXT: vcmpneqsd %xmm1, %xmm0, %k1162; AVX512-NEXT: kandw %k0, %k1, %k0163; AVX512-NEXT: kmovw %k0, %eax164; AVX512-NEXT: # kill: def $al killed $al killed $eax165; AVX512-NEXT: retq166 %f1 = fcmp une double %w, %x167 %f2 = fcmp ugt double %y, %z168 %r = and i1 %f1, %f2169 ret i1 %r170}171 172define i1 @ult_uge_or_f64(double %w, double %x, double %y, double %z) {173; SSE2-LABEL: ult_uge_or_f64:174; SSE2: # %bb.0:175; SSE2-NEXT: cmpnltsd %xmm3, %xmm2176; SSE2-NEXT: cmpnlesd %xmm0, %xmm1177; SSE2-NEXT: orpd %xmm2, %xmm1178; SSE2-NEXT: movd %xmm1, %eax179; SSE2-NEXT: # kill: def $al killed $al killed $eax180; SSE2-NEXT: retq181;182; AVX1-LABEL: ult_uge_or_f64:183; AVX1: # %bb.0:184; AVX1-NEXT: vcmpnltsd %xmm3, %xmm2, %xmm2185; AVX1-NEXT: vcmpnlesd %xmm0, %xmm1, %xmm0186; AVX1-NEXT: vorpd %xmm2, %xmm0, %xmm0187; AVX1-NEXT: vmovd %xmm0, %eax188; AVX1-NEXT: # kill: def $al killed $al killed $eax189; AVX1-NEXT: retq190;191; AVX512-LABEL: ult_uge_or_f64:192; AVX512: # %bb.0:193; AVX512-NEXT: vcmpnltsd %xmm3, %xmm2, %k0194; AVX512-NEXT: vcmpnlesd %xmm0, %xmm1, %k1195; AVX512-NEXT: korw %k0, %k1, %k0196; AVX512-NEXT: kmovw %k0, %eax197; AVX512-NEXT: # kill: def $al killed $al killed $eax198; AVX512-NEXT: retq199 %f1 = fcmp ult double %w, %x200 %f2 = fcmp uge double %y, %z201 %r = or i1 %f1, %f2202 ret i1 %r203}204 205define i1 @une_uno_xor_f64(double %w, double %x, double %y, double %z) {206; SSE2-LABEL: une_uno_xor_f64:207; SSE2: # %bb.0:208; SSE2-NEXT: cmpunordsd %xmm3, %xmm2209; SSE2-NEXT: cmpneqsd %xmm1, %xmm0210; SSE2-NEXT: xorpd %xmm2, %xmm0211; SSE2-NEXT: movd %xmm0, %eax212; SSE2-NEXT: # kill: def $al killed $al killed $eax213; SSE2-NEXT: retq214;215; AVX1-LABEL: une_uno_xor_f64:216; AVX1: # %bb.0:217; AVX1-NEXT: vcmpunordsd %xmm3, %xmm2, %xmm2218; AVX1-NEXT: vcmpneqsd %xmm1, %xmm0, %xmm0219; AVX1-NEXT: vxorpd %xmm2, %xmm0, %xmm0220; AVX1-NEXT: vmovd %xmm0, %eax221; AVX1-NEXT: # kill: def $al killed $al killed $eax222; AVX1-NEXT: retq223;224; AVX512-LABEL: une_uno_xor_f64:225; AVX512: # %bb.0:226; AVX512-NEXT: vcmpunordsd %xmm3, %xmm2, %k0227; AVX512-NEXT: vcmpneqsd %xmm1, %xmm0, %k1228; AVX512-NEXT: kxorw %k0, %k1, %k0229; AVX512-NEXT: kmovw %k0, %eax230; AVX512-NEXT: # kill: def $al killed $al killed $eax231; AVX512-NEXT: retq232 %f1 = fcmp une double %w, %x233 %f2 = fcmp uno double %y, %z234 %r = xor i1 %f1, %f2235 ret i1 %r236}237 238; This uses ucomis because the types do not match.239; TODO: Merge down to narrow type?240 241define i1 @olt_olt_and_f32_f64(float %w, float %x, double %y, double %z) {242; SSE2-LABEL: olt_olt_and_f32_f64:243; SSE2: # %bb.0:244; SSE2-NEXT: ucomiss %xmm0, %xmm1245; SSE2-NEXT: seta %cl246; SSE2-NEXT: ucomisd %xmm2, %xmm3247; SSE2-NEXT: seta %al248; SSE2-NEXT: andb %cl, %al249; SSE2-NEXT: retq250;251; AVX-LABEL: olt_olt_and_f32_f64:252; AVX: # %bb.0:253; AVX-NEXT: vucomiss %xmm0, %xmm1254; AVX-NEXT: seta %cl255; AVX-NEXT: vucomisd %xmm2, %xmm3256; AVX-NEXT: seta %al257; AVX-NEXT: andb %cl, %al258; AVX-NEXT: retq259 %f1 = fcmp olt float %w, %x260 %f2 = fcmp olt double %y, %z261 %r = and i1 %f1, %f2262 ret i1 %r263}264 265; This uses ucomis because of extra uses.266 267define i1 @une_uno_xor_f64_use1(double %w, double %x, double %y, double %z, ptr %p) {268; SSE2-LABEL: une_uno_xor_f64_use1:269; SSE2: # %bb.0:270; SSE2-NEXT: ucomisd %xmm1, %xmm0271; SSE2-NEXT: setp %al272; SSE2-NEXT: setne %cl273; SSE2-NEXT: orb %al, %cl274; SSE2-NEXT: movb %cl, (%rdi)275; SSE2-NEXT: ucomisd %xmm3, %xmm2276; SSE2-NEXT: setp %al277; SSE2-NEXT: xorb %cl, %al278; SSE2-NEXT: retq279;280; AVX-LABEL: une_uno_xor_f64_use1:281; AVX: # %bb.0:282; AVX-NEXT: vucomisd %xmm1, %xmm0283; AVX-NEXT: setp %al284; AVX-NEXT: setne %cl285; AVX-NEXT: orb %al, %cl286; AVX-NEXT: movb %cl, (%rdi)287; AVX-NEXT: vucomisd %xmm3, %xmm2288; AVX-NEXT: setp %al289; AVX-NEXT: xorb %cl, %al290; AVX-NEXT: retq291 %f1 = fcmp une double %w, %x292 store i1 %f1, ptr %p293 %f2 = fcmp uno double %y, %z294 %r = xor i1 %f1, %f2295 ret i1 %r296}297 298; This uses ucomis because of extra uses.299 300define i1 @une_uno_xor_f64_use2(double %w, double %x, double %y, double %z, ptr %p) {301; SSE2-LABEL: une_uno_xor_f64_use2:302; SSE2: # %bb.0:303; SSE2-NEXT: ucomisd %xmm1, %xmm0304; SSE2-NEXT: setp %al305; SSE2-NEXT: setne %cl306; SSE2-NEXT: orb %al, %cl307; SSE2-NEXT: ucomisd %xmm3, %xmm2308; SSE2-NEXT: setp %al309; SSE2-NEXT: setp (%rdi)310; SSE2-NEXT: xorb %cl, %al311; SSE2-NEXT: retq312;313; AVX-LABEL: une_uno_xor_f64_use2:314; AVX: # %bb.0:315; AVX-NEXT: vucomisd %xmm1, %xmm0316; AVX-NEXT: setp %al317; AVX-NEXT: setne %cl318; AVX-NEXT: orb %al, %cl319; AVX-NEXT: vucomisd %xmm3, %xmm2320; AVX-NEXT: setp %al321; AVX-NEXT: setp (%rdi)322; AVX-NEXT: xorb %cl, %al323; AVX-NEXT: retq324 %f1 = fcmp une double %w, %x325 %f2 = fcmp uno double %y, %z326 store i1 %f2, ptr %p327 %r = xor i1 %f1, %f2328 ret i1 %r329}330 331 332; bool f32cmp3(float x, float y, float z, float w) {333; return ((x > 0) || (y > 0)) != (z < w);334; }335 336define i1 @f32cmp3(float %x, float %y, float %z, float %w) {337; SSE2-LABEL: f32cmp3:338; SSE2: # %bb.0:339; SSE2-NEXT: xorps %xmm4, %xmm4340; SSE2-NEXT: xorps %xmm5, %xmm5341; SSE2-NEXT: cmpltss %xmm1, %xmm5342; SSE2-NEXT: cmpltss %xmm0, %xmm4343; SSE2-NEXT: orps %xmm5, %xmm4344; SSE2-NEXT: movd %xmm4, %ecx345; SSE2-NEXT: ucomiss %xmm2, %xmm3346; SSE2-NEXT: seta %al347; SSE2-NEXT: xorb %cl, %al348; SSE2-NEXT: retq349;350; AVX1-LABEL: f32cmp3:351; AVX1: # %bb.0:352; AVX1-NEXT: vxorps %xmm4, %xmm4, %xmm4353; AVX1-NEXT: vcmpltss %xmm1, %xmm4, %xmm1354; AVX1-NEXT: vcmpltss %xmm0, %xmm4, %xmm0355; AVX1-NEXT: vorps %xmm1, %xmm0, %xmm0356; AVX1-NEXT: vmovd %xmm0, %ecx357; AVX1-NEXT: vucomiss %xmm2, %xmm3358; AVX1-NEXT: seta %al359; AVX1-NEXT: xorb %cl, %al360; AVX1-NEXT: retq361;362; AVX512-LABEL: f32cmp3:363; AVX512: # %bb.0:364; AVX512-NEXT: vxorps %xmm4, %xmm4, %xmm4365; AVX512-NEXT: vcmpltss %xmm1, %xmm4, %k0366; AVX512-NEXT: vcmpltss %xmm0, %xmm4, %k1367; AVX512-NEXT: korw %k0, %k1, %k0368; AVX512-NEXT: kmovw %k0, %ecx369; AVX512-NEXT: vucomiss %xmm2, %xmm3370; AVX512-NEXT: seta %al371; AVX512-NEXT: xorb %cl, %al372; AVX512-NEXT: retq373 %cmpx = fcmp ogt float %x, 0.0374 %cmpy = fcmp ogt float %y, 0.0375 %or = select i1 %cmpx, i1 true, i1 %cmpy376 %cmpzw = fcmp olt float %z, %w377 %r = xor i1 %or, %cmpzw378 ret i1 %r379}380 381define i1 @PR140534(i32 %a0, i32 %a1, i32 %a2) {382; SSE2-LABEL: PR140534:383; SSE2: # %bb.0:384; SSE2-NEXT: movl %edi, %eax385; SSE2-NEXT: cvtsi2sd %rax, %xmm0386; SSE2-NEXT: movl %esi, %eax387; SSE2-NEXT: cvtsi2sd %rax, %xmm1388; SSE2-NEXT: movl %edx, %eax389; SSE2-NEXT: cvtsi2sd %rax, %xmm2390; SSE2-NEXT: mulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1391; SSE2-NEXT: movapd %xmm1, %xmm3392; SSE2-NEXT: cmpltsd %xmm2, %xmm3393; SSE2-NEXT: cmpltsd %xmm0, %xmm1394; SSE2-NEXT: orpd %xmm3, %xmm1395; SSE2-NEXT: movd %xmm1, %eax396; SSE2-NEXT: # kill: def $al killed $al killed $eax397; SSE2-NEXT: retq398;399; AVX1-LABEL: PR140534:400; AVX1: # %bb.0:401; AVX1-NEXT: movl %edi, %eax402; AVX1-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0403; AVX1-NEXT: movl %esi, %eax404; AVX1-NEXT: vcvtsi2sd %rax, %xmm15, %xmm1405; AVX1-NEXT: movl %edx, %eax406; AVX1-NEXT: vcvtsi2sd %rax, %xmm15, %xmm2407; AVX1-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1408; AVX1-NEXT: vcmpltsd %xmm2, %xmm1, %xmm2409; AVX1-NEXT: vcmpltsd %xmm0, %xmm1, %xmm0410; AVX1-NEXT: vorpd %xmm2, %xmm0, %xmm0411; AVX1-NEXT: vmovd %xmm0, %eax412; AVX1-NEXT: # kill: def $al killed $al killed $eax413; AVX1-NEXT: retq414;415; AVX512-LABEL: PR140534:416; AVX512: # %bb.0:417; AVX512-NEXT: vcvtusi2sd %edi, %xmm15, %xmm0418; AVX512-NEXT: vcvtusi2sd %esi, %xmm15, %xmm1419; AVX512-NEXT: vcvtusi2sd %edx, %xmm15, %xmm2420; AVX512-NEXT: vmulsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1421; AVX512-NEXT: vcmpltsd %xmm2, %xmm1, %k0422; AVX512-NEXT: vcmpltsd %xmm0, %xmm1, %k1423; AVX512-NEXT: korw %k0, %k1, %k0424; AVX512-NEXT: kmovw %k0, %eax425; AVX512-NEXT: # kill: def $al killed $al killed $eax426; AVX512-NEXT: retq427 %conv0 = uitofp i32 %a0 to double428 %conv1 = uitofp i32 %a1 to double429 %conv2 = uitofp i32 %a2 to double430 %mul = fmul double %conv1, 0x3FF6A09E667F3BCD431 %cmp0 = fcmp olt double %mul, %conv0432 %cmp2 = fcmp olt double %mul, %conv2433 %or = or i1 %cmp0, %cmp2434 ret i1 %or435}436