694 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE23; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=CHECK,SSE,SSE44; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=CHECK,AVX,AVX15; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f | FileCheck %s --check-prefixes=CHECK,AVX,AVX5126 7declare float @fmaxf(float, float)8declare double @fmax(double, double)9declare x86_fp80 @fmaxl(x86_fp80, x86_fp80)10declare float @llvm.maxnum.f32(float, float)11declare double @llvm.maxnum.f64(double, double)12declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80)13 14declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>)15declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)16declare <8 x float> @llvm.maxnum.v8f32(<8 x float>, <8 x float>)17declare <16 x float> @llvm.maxnum.v16f32(<16 x float>, <16 x float>)18declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>)19declare <4 x double> @llvm.maxnum.v4f64(<4 x double>, <4 x double>)20declare <8 x double> @llvm.maxnum.v8f64(<8 x double>, <8 x double>)21 22; FIXME: As the vector tests show, the SSE run shouldn't need this many moves.23 24define float @test_fmaxf(float %x, float %y) {25; SSE2-LABEL: test_fmaxf:26; SSE2: # %bb.0:27; SSE2-NEXT: movaps %xmm0, %xmm228; SSE2-NEXT: cmpunordss %xmm0, %xmm229; SSE2-NEXT: movaps %xmm2, %xmm330; SSE2-NEXT: andps %xmm1, %xmm331; SSE2-NEXT: maxss %xmm0, %xmm132; SSE2-NEXT: andnps %xmm1, %xmm233; SSE2-NEXT: orps %xmm3, %xmm234; SSE2-NEXT: movaps %xmm2, %xmm035; SSE2-NEXT: retq36;37; SSE4-LABEL: test_fmaxf:38; SSE4: # %bb.0:39; SSE4-NEXT: movaps %xmm1, %xmm240; SSE4-NEXT: maxss %xmm0, %xmm241; SSE4-NEXT: cmpunordss %xmm0, %xmm042; SSE4-NEXT: blendvps %xmm0, %xmm1, %xmm243; SSE4-NEXT: movaps %xmm2, %xmm044; SSE4-NEXT: retq45;46; AVX1-LABEL: test_fmaxf:47; AVX1: # %bb.0:48; AVX1-NEXT: vmaxss %xmm0, %xmm1, %xmm249; AVX1-NEXT: vcmpunordss %xmm0, %xmm0, %xmm050; AVX1-NEXT: vblendvps %xmm0, %xmm1, %xmm2, %xmm051; AVX1-NEXT: retq52;53; AVX512-LABEL: test_fmaxf:54; AVX512: # %bb.0:55; AVX512-NEXT: vmaxss %xmm0, %xmm1, %xmm256; AVX512-NEXT: vcmpunordss %xmm0, %xmm0, %k157; AVX512-NEXT: vmovss %xmm1, %xmm2, %xmm2 {%k1}58; AVX512-NEXT: vmovaps %xmm2, %xmm059; AVX512-NEXT: retq60 %z = call float @fmaxf(float %x, float %y) readnone61 ret float %z62}63 64define float @test_fmaxf_minsize(float %x, float %y) minsize {65; CHECK-LABEL: test_fmaxf_minsize:66; CHECK: # %bb.0:67; CHECK-NEXT: jmp fmaxf@PLT # TAILCALL68 %z = call float @fmaxf(float %x, float %y) readnone69 ret float %z70}71 72; FIXME: As the vector tests show, the SSE run shouldn't need this many moves.73 74define double @test_fmax(double %x, double %y) {75; SSE2-LABEL: test_fmax:76; SSE2: # %bb.0:77; SSE2-NEXT: movapd %xmm0, %xmm278; SSE2-NEXT: cmpunordsd %xmm0, %xmm279; SSE2-NEXT: movapd %xmm2, %xmm380; SSE2-NEXT: andpd %xmm1, %xmm381; SSE2-NEXT: maxsd %xmm0, %xmm182; SSE2-NEXT: andnpd %xmm1, %xmm283; SSE2-NEXT: orpd %xmm3, %xmm284; SSE2-NEXT: movapd %xmm2, %xmm085; SSE2-NEXT: retq86;87; SSE4-LABEL: test_fmax:88; SSE4: # %bb.0:89; SSE4-NEXT: movapd %xmm1, %xmm290; SSE4-NEXT: maxsd %xmm0, %xmm291; SSE4-NEXT: cmpunordsd %xmm0, %xmm092; SSE4-NEXT: blendvpd %xmm0, %xmm1, %xmm293; SSE4-NEXT: movapd %xmm2, %xmm094; SSE4-NEXT: retq95;96; AVX1-LABEL: test_fmax:97; AVX1: # %bb.0:98; AVX1-NEXT: vmaxsd %xmm0, %xmm1, %xmm299; AVX1-NEXT: vcmpunordsd %xmm0, %xmm0, %xmm0100; AVX1-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm0101; AVX1-NEXT: retq102;103; AVX512-LABEL: test_fmax:104; AVX512: # %bb.0:105; AVX512-NEXT: vmaxsd %xmm0, %xmm1, %xmm2106; AVX512-NEXT: vcmpunordsd %xmm0, %xmm0, %k1107; AVX512-NEXT: vmovsd %xmm1, %xmm2, %xmm2 {%k1}108; AVX512-NEXT: vmovapd %xmm2, %xmm0109; AVX512-NEXT: retq110 %z = call double @fmax(double %x, double %y) readnone111 ret double %z112}113 114define x86_fp80 @test_fmaxl(x86_fp80 %x, x86_fp80 %y) {115; CHECK-LABEL: test_fmaxl:116; CHECK: # %bb.0:117; CHECK-NEXT: subq $40, %rsp118; CHECK-NEXT: .cfi_def_cfa_offset 48119; CHECK-NEXT: fldt {{[0-9]+}}(%rsp)120; CHECK-NEXT: fldt {{[0-9]+}}(%rsp)121; CHECK-NEXT: fstpt {{[0-9]+}}(%rsp)122; CHECK-NEXT: fstpt (%rsp)123; CHECK-NEXT: callq fmaxl@PLT124; CHECK-NEXT: addq $40, %rsp125; CHECK-NEXT: .cfi_def_cfa_offset 8126; CHECK-NEXT: retq127 %z = call x86_fp80 @fmaxl(x86_fp80 %x, x86_fp80 %y) readnone128 ret x86_fp80 %z129}130 131define float @test_intrinsic_fmaxf(float %x, float %y) {132; SSE2-LABEL: test_intrinsic_fmaxf:133; SSE2: # %bb.0:134; SSE2-NEXT: movaps %xmm0, %xmm2135; SSE2-NEXT: cmpunordss %xmm0, %xmm2136; SSE2-NEXT: movaps %xmm2, %xmm3137; SSE2-NEXT: andps %xmm1, %xmm3138; SSE2-NEXT: maxss %xmm0, %xmm1139; SSE2-NEXT: andnps %xmm1, %xmm2140; SSE2-NEXT: orps %xmm3, %xmm2141; SSE2-NEXT: movaps %xmm2, %xmm0142; SSE2-NEXT: retq143;144; SSE4-LABEL: test_intrinsic_fmaxf:145; SSE4: # %bb.0:146; SSE4-NEXT: movaps %xmm1, %xmm2147; SSE4-NEXT: maxss %xmm0, %xmm2148; SSE4-NEXT: cmpunordss %xmm0, %xmm0149; SSE4-NEXT: blendvps %xmm0, %xmm1, %xmm2150; SSE4-NEXT: movaps %xmm2, %xmm0151; SSE4-NEXT: retq152;153; AVX1-LABEL: test_intrinsic_fmaxf:154; AVX1: # %bb.0:155; AVX1-NEXT: vmaxss %xmm0, %xmm1, %xmm2156; AVX1-NEXT: vcmpunordss %xmm0, %xmm0, %xmm0157; AVX1-NEXT: vblendvps %xmm0, %xmm1, %xmm2, %xmm0158; AVX1-NEXT: retq159;160; AVX512-LABEL: test_intrinsic_fmaxf:161; AVX512: # %bb.0:162; AVX512-NEXT: vmaxss %xmm0, %xmm1, %xmm2163; AVX512-NEXT: vcmpunordss %xmm0, %xmm0, %k1164; AVX512-NEXT: vmovss %xmm1, %xmm2, %xmm2 {%k1}165; AVX512-NEXT: vmovaps %xmm2, %xmm0166; AVX512-NEXT: retq167 %z = call float @llvm.maxnum.f32(float %x, float %y) readnone168 ret float %z169}170 171define double @test_intrinsic_fmax(double %x, double %y) {172; SSE2-LABEL: test_intrinsic_fmax:173; SSE2: # %bb.0:174; SSE2-NEXT: movapd %xmm0, %xmm2175; SSE2-NEXT: cmpunordsd %xmm0, %xmm2176; SSE2-NEXT: movapd %xmm2, %xmm3177; SSE2-NEXT: andpd %xmm1, %xmm3178; SSE2-NEXT: maxsd %xmm0, %xmm1179; SSE2-NEXT: andnpd %xmm1, %xmm2180; SSE2-NEXT: orpd %xmm3, %xmm2181; SSE2-NEXT: movapd %xmm2, %xmm0182; SSE2-NEXT: retq183;184; SSE4-LABEL: test_intrinsic_fmax:185; SSE4: # %bb.0:186; SSE4-NEXT: movapd %xmm1, %xmm2187; SSE4-NEXT: maxsd %xmm0, %xmm2188; SSE4-NEXT: cmpunordsd %xmm0, %xmm0189; SSE4-NEXT: blendvpd %xmm0, %xmm1, %xmm2190; SSE4-NEXT: movapd %xmm2, %xmm0191; SSE4-NEXT: retq192;193; AVX1-LABEL: test_intrinsic_fmax:194; AVX1: # %bb.0:195; AVX1-NEXT: vmaxsd %xmm0, %xmm1, %xmm2196; AVX1-NEXT: vcmpunordsd %xmm0, %xmm0, %xmm0197; AVX1-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm0198; AVX1-NEXT: retq199;200; AVX512-LABEL: test_intrinsic_fmax:201; AVX512: # %bb.0:202; AVX512-NEXT: vmaxsd %xmm0, %xmm1, %xmm2203; AVX512-NEXT: vcmpunordsd %xmm0, %xmm0, %k1204; AVX512-NEXT: vmovsd %xmm1, %xmm2, %xmm2 {%k1}205; AVX512-NEXT: vmovapd %xmm2, %xmm0206; AVX512-NEXT: retq207 %z = call double @llvm.maxnum.f64(double %x, double %y) readnone208 ret double %z209}210 211define x86_fp80 @test_intrinsic_fmaxl(x86_fp80 %x, x86_fp80 %y) {212; CHECK-LABEL: test_intrinsic_fmaxl:213; CHECK: # %bb.0:214; CHECK-NEXT: subq $40, %rsp215; CHECK-NEXT: .cfi_def_cfa_offset 48216; CHECK-NEXT: fldt {{[0-9]+}}(%rsp)217; CHECK-NEXT: fldt {{[0-9]+}}(%rsp)218; CHECK-NEXT: fstpt {{[0-9]+}}(%rsp)219; CHECK-NEXT: fstpt (%rsp)220; CHECK-NEXT: callq fmaxl@PLT221; CHECK-NEXT: addq $40, %rsp222; CHECK-NEXT: .cfi_def_cfa_offset 8223; CHECK-NEXT: retq224 %z = call x86_fp80 @llvm.maxnum.f80(x86_fp80 %x, x86_fp80 %y) readnone225 ret x86_fp80 %z226}227 228define <2 x float> @test_intrinsic_fmax_v2f32(<2 x float> %x, <2 x float> %y) {229; SSE2-LABEL: test_intrinsic_fmax_v2f32:230; SSE2: # %bb.0:231; SSE2-NEXT: movaps %xmm1, %xmm2232; SSE2-NEXT: maxps %xmm0, %xmm2233; SSE2-NEXT: cmpunordps %xmm0, %xmm0234; SSE2-NEXT: andps %xmm0, %xmm1235; SSE2-NEXT: andnps %xmm2, %xmm0236; SSE2-NEXT: orps %xmm1, %xmm0237; SSE2-NEXT: retq238;239; SSE4-LABEL: test_intrinsic_fmax_v2f32:240; SSE4: # %bb.0:241; SSE4-NEXT: movaps %xmm1, %xmm2242; SSE4-NEXT: maxps %xmm0, %xmm2243; SSE4-NEXT: cmpunordps %xmm0, %xmm0244; SSE4-NEXT: blendvps %xmm0, %xmm1, %xmm2245; SSE4-NEXT: movaps %xmm2, %xmm0246; SSE4-NEXT: retq247;248; AVX-LABEL: test_intrinsic_fmax_v2f32:249; AVX: # %bb.0:250; AVX-NEXT: vmaxps %xmm0, %xmm1, %xmm2251; AVX-NEXT: vcmpunordps %xmm0, %xmm0, %xmm0252; AVX-NEXT: vblendvps %xmm0, %xmm1, %xmm2, %xmm0253; AVX-NEXT: retq254 %z = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> %y) readnone255 ret <2 x float> %z256}257 258define <4 x float> @test_intrinsic_fmax_v4f32(<4 x float> %x, <4 x float> %y) {259; SSE2-LABEL: test_intrinsic_fmax_v4f32:260; SSE2: # %bb.0:261; SSE2-NEXT: movaps %xmm1, %xmm2262; SSE2-NEXT: maxps %xmm0, %xmm2263; SSE2-NEXT: cmpunordps %xmm0, %xmm0264; SSE2-NEXT: andps %xmm0, %xmm1265; SSE2-NEXT: andnps %xmm2, %xmm0266; SSE2-NEXT: orps %xmm1, %xmm0267; SSE2-NEXT: retq268;269; SSE4-LABEL: test_intrinsic_fmax_v4f32:270; SSE4: # %bb.0:271; SSE4-NEXT: movaps %xmm1, %xmm2272; SSE4-NEXT: maxps %xmm0, %xmm2273; SSE4-NEXT: cmpunordps %xmm0, %xmm0274; SSE4-NEXT: blendvps %xmm0, %xmm1, %xmm2275; SSE4-NEXT: movaps %xmm2, %xmm0276; SSE4-NEXT: retq277;278; AVX-LABEL: test_intrinsic_fmax_v4f32:279; AVX: # %bb.0:280; AVX-NEXT: vmaxps %xmm0, %xmm1, %xmm2281; AVX-NEXT: vcmpunordps %xmm0, %xmm0, %xmm0282; AVX-NEXT: vblendvps %xmm0, %xmm1, %xmm2, %xmm0283; AVX-NEXT: retq284 %z = call <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y) readnone285 ret <4 x float> %z286}287 288define <8 x float> @test_intrinsic_fmax_v8f32(<8 x float> %x, <8 x float> %y) {289; SSE2-LABEL: test_intrinsic_fmax_v8f32:290; SSE2: # %bb.0:291; SSE2-NEXT: movaps %xmm2, %xmm4292; SSE2-NEXT: maxps %xmm0, %xmm4293; SSE2-NEXT: cmpunordps %xmm0, %xmm0294; SSE2-NEXT: andps %xmm0, %xmm2295; SSE2-NEXT: andnps %xmm4, %xmm0296; SSE2-NEXT: orps %xmm2, %xmm0297; SSE2-NEXT: movaps %xmm3, %xmm2298; SSE2-NEXT: maxps %xmm1, %xmm2299; SSE2-NEXT: cmpunordps %xmm1, %xmm1300; SSE2-NEXT: andps %xmm1, %xmm3301; SSE2-NEXT: andnps %xmm2, %xmm1302; SSE2-NEXT: orps %xmm3, %xmm1303; SSE2-NEXT: retq304;305; SSE4-LABEL: test_intrinsic_fmax_v8f32:306; SSE4: # %bb.0:307; SSE4-NEXT: movaps %xmm1, %xmm5308; SSE4-NEXT: movaps %xmm2, %xmm4309; SSE4-NEXT: maxps %xmm0, %xmm4310; SSE4-NEXT: cmpunordps %xmm0, %xmm0311; SSE4-NEXT: blendvps %xmm0, %xmm2, %xmm4312; SSE4-NEXT: movaps %xmm3, %xmm1313; SSE4-NEXT: maxps %xmm5, %xmm1314; SSE4-NEXT: cmpunordps %xmm5, %xmm5315; SSE4-NEXT: movaps %xmm5, %xmm0316; SSE4-NEXT: blendvps %xmm0, %xmm3, %xmm1317; SSE4-NEXT: movaps %xmm4, %xmm0318; SSE4-NEXT: retq319;320; AVX-LABEL: test_intrinsic_fmax_v8f32:321; AVX: # %bb.0:322; AVX-NEXT: vmaxps %ymm0, %ymm1, %ymm2323; AVX-NEXT: vcmpunordps %ymm0, %ymm0, %ymm0324; AVX-NEXT: vblendvps %ymm0, %ymm1, %ymm2, %ymm0325; AVX-NEXT: retq326 %z = call <8 x float> @llvm.maxnum.v8f32(<8 x float> %x, <8 x float> %y) readnone327 ret <8 x float> %z328}329 330define <16 x float> @test_intrinsic_fmax_v16f32(<16 x float> %x, <16 x float> %y) {331; SSE2-LABEL: test_intrinsic_fmax_v16f32:332; SSE2: # %bb.0:333; SSE2-NEXT: movaps %xmm4, %xmm8334; SSE2-NEXT: maxps %xmm0, %xmm8335; SSE2-NEXT: cmpunordps %xmm0, %xmm0336; SSE2-NEXT: andps %xmm0, %xmm4337; SSE2-NEXT: andnps %xmm8, %xmm0338; SSE2-NEXT: orps %xmm4, %xmm0339; SSE2-NEXT: movaps %xmm5, %xmm4340; SSE2-NEXT: maxps %xmm1, %xmm4341; SSE2-NEXT: cmpunordps %xmm1, %xmm1342; SSE2-NEXT: andps %xmm1, %xmm5343; SSE2-NEXT: andnps %xmm4, %xmm1344; SSE2-NEXT: orps %xmm5, %xmm1345; SSE2-NEXT: movaps %xmm6, %xmm4346; SSE2-NEXT: maxps %xmm2, %xmm4347; SSE2-NEXT: cmpunordps %xmm2, %xmm2348; SSE2-NEXT: andps %xmm2, %xmm6349; SSE2-NEXT: andnps %xmm4, %xmm2350; SSE2-NEXT: orps %xmm6, %xmm2351; SSE2-NEXT: movaps %xmm7, %xmm4352; SSE2-NEXT: maxps %xmm3, %xmm4353; SSE2-NEXT: cmpunordps %xmm3, %xmm3354; SSE2-NEXT: andps %xmm3, %xmm7355; SSE2-NEXT: andnps %xmm4, %xmm3356; SSE2-NEXT: orps %xmm7, %xmm3357; SSE2-NEXT: retq358;359; SSE4-LABEL: test_intrinsic_fmax_v16f32:360; SSE4: # %bb.0:361; SSE4-NEXT: movaps %xmm3, %xmm11362; SSE4-NEXT: movaps %xmm2, %xmm10363; SSE4-NEXT: movaps %xmm1, %xmm9364; SSE4-NEXT: movaps %xmm4, %xmm8365; SSE4-NEXT: maxps %xmm0, %xmm8366; SSE4-NEXT: cmpunordps %xmm0, %xmm0367; SSE4-NEXT: blendvps %xmm0, %xmm4, %xmm8368; SSE4-NEXT: movaps %xmm5, %xmm1369; SSE4-NEXT: maxps %xmm9, %xmm1370; SSE4-NEXT: cmpunordps %xmm9, %xmm9371; SSE4-NEXT: movaps %xmm9, %xmm0372; SSE4-NEXT: blendvps %xmm0, %xmm5, %xmm1373; SSE4-NEXT: movaps %xmm6, %xmm2374; SSE4-NEXT: maxps %xmm10, %xmm2375; SSE4-NEXT: cmpunordps %xmm10, %xmm10376; SSE4-NEXT: movaps %xmm10, %xmm0377; SSE4-NEXT: blendvps %xmm0, %xmm6, %xmm2378; SSE4-NEXT: movaps %xmm7, %xmm3379; SSE4-NEXT: maxps %xmm11, %xmm3380; SSE4-NEXT: cmpunordps %xmm11, %xmm11381; SSE4-NEXT: movaps %xmm11, %xmm0382; SSE4-NEXT: blendvps %xmm0, %xmm7, %xmm3383; SSE4-NEXT: movaps %xmm8, %xmm0384; SSE4-NEXT: retq385;386; AVX1-LABEL: test_intrinsic_fmax_v16f32:387; AVX1: # %bb.0:388; AVX1-NEXT: vmaxps %ymm0, %ymm2, %ymm4389; AVX1-NEXT: vcmpunordps %ymm0, %ymm0, %ymm0390; AVX1-NEXT: vblendvps %ymm0, %ymm2, %ymm4, %ymm0391; AVX1-NEXT: vmaxps %ymm1, %ymm3, %ymm2392; AVX1-NEXT: vcmpunordps %ymm1, %ymm1, %ymm1393; AVX1-NEXT: vblendvps %ymm1, %ymm3, %ymm2, %ymm1394; AVX1-NEXT: retq395;396; AVX512-LABEL: test_intrinsic_fmax_v16f32:397; AVX512: # %bb.0:398; AVX512-NEXT: vmaxps %zmm0, %zmm1, %zmm2399; AVX512-NEXT: vcmpunordps %zmm0, %zmm0, %k1400; AVX512-NEXT: vmovaps %zmm1, %zmm2 {%k1}401; AVX512-NEXT: vmovaps %zmm2, %zmm0402; AVX512-NEXT: retq403 %z = call <16 x float> @llvm.maxnum.v16f32(<16 x float> %x, <16 x float> %y) readnone404 ret <16 x float> %z405}406 407define <2 x double> @test_intrinsic_fmax_v2f64(<2 x double> %x, <2 x double> %y) {408; SSE2-LABEL: test_intrinsic_fmax_v2f64:409; SSE2: # %bb.0:410; SSE2-NEXT: movapd %xmm1, %xmm2411; SSE2-NEXT: maxpd %xmm0, %xmm2412; SSE2-NEXT: cmpunordpd %xmm0, %xmm0413; SSE2-NEXT: andpd %xmm0, %xmm1414; SSE2-NEXT: andnpd %xmm2, %xmm0415; SSE2-NEXT: orpd %xmm1, %xmm0416; SSE2-NEXT: retq417;418; SSE4-LABEL: test_intrinsic_fmax_v2f64:419; SSE4: # %bb.0:420; SSE4-NEXT: movapd %xmm1, %xmm2421; SSE4-NEXT: maxpd %xmm0, %xmm2422; SSE4-NEXT: cmpunordpd %xmm0, %xmm0423; SSE4-NEXT: blendvpd %xmm0, %xmm1, %xmm2424; SSE4-NEXT: movapd %xmm2, %xmm0425; SSE4-NEXT: retq426;427; AVX-LABEL: test_intrinsic_fmax_v2f64:428; AVX: # %bb.0:429; AVX-NEXT: vmaxpd %xmm0, %xmm1, %xmm2430; AVX-NEXT: vcmpunordpd %xmm0, %xmm0, %xmm0431; AVX-NEXT: vblendvpd %xmm0, %xmm1, %xmm2, %xmm0432; AVX-NEXT: retq433 %z = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double> %y) readnone434 ret <2 x double> %z435}436 437define <4 x double> @test_intrinsic_fmax_v4f64(<4 x double> %x, <4 x double> %y) {438; SSE2-LABEL: test_intrinsic_fmax_v4f64:439; SSE2: # %bb.0:440; SSE2-NEXT: movapd %xmm2, %xmm4441; SSE2-NEXT: maxpd %xmm0, %xmm4442; SSE2-NEXT: cmpunordpd %xmm0, %xmm0443; SSE2-NEXT: andpd %xmm0, %xmm2444; SSE2-NEXT: andnpd %xmm4, %xmm0445; SSE2-NEXT: orpd %xmm2, %xmm0446; SSE2-NEXT: movapd %xmm3, %xmm2447; SSE2-NEXT: maxpd %xmm1, %xmm2448; SSE2-NEXT: cmpunordpd %xmm1, %xmm1449; SSE2-NEXT: andpd %xmm1, %xmm3450; SSE2-NEXT: andnpd %xmm2, %xmm1451; SSE2-NEXT: orpd %xmm3, %xmm1452; SSE2-NEXT: retq453;454; SSE4-LABEL: test_intrinsic_fmax_v4f64:455; SSE4: # %bb.0:456; SSE4-NEXT: movapd %xmm1, %xmm5457; SSE4-NEXT: movapd %xmm2, %xmm4458; SSE4-NEXT: maxpd %xmm0, %xmm4459; SSE4-NEXT: cmpunordpd %xmm0, %xmm0460; SSE4-NEXT: blendvpd %xmm0, %xmm2, %xmm4461; SSE4-NEXT: movapd %xmm3, %xmm1462; SSE4-NEXT: maxpd %xmm5, %xmm1463; SSE4-NEXT: cmpunordpd %xmm5, %xmm5464; SSE4-NEXT: movapd %xmm5, %xmm0465; SSE4-NEXT: blendvpd %xmm0, %xmm3, %xmm1466; SSE4-NEXT: movapd %xmm4, %xmm0467; SSE4-NEXT: retq468;469; AVX-LABEL: test_intrinsic_fmax_v4f64:470; AVX: # %bb.0:471; AVX-NEXT: vmaxpd %ymm0, %ymm1, %ymm2472; AVX-NEXT: vcmpunordpd %ymm0, %ymm0, %ymm0473; AVX-NEXT: vblendvpd %ymm0, %ymm1, %ymm2, %ymm0474; AVX-NEXT: retq475 %z = call <4 x double> @llvm.maxnum.v4f64(<4 x double> %x, <4 x double> %y) readnone476 ret <4 x double> %z477}478 479define <8 x double> @test_intrinsic_fmax_v8f64(<8 x double> %x, <8 x double> %y) {480; SSE2-LABEL: test_intrinsic_fmax_v8f64:481; SSE2: # %bb.0:482; SSE2-NEXT: movapd %xmm4, %xmm8483; SSE2-NEXT: maxpd %xmm0, %xmm8484; SSE2-NEXT: cmpunordpd %xmm0, %xmm0485; SSE2-NEXT: andpd %xmm0, %xmm4486; SSE2-NEXT: andnpd %xmm8, %xmm0487; SSE2-NEXT: orpd %xmm4, %xmm0488; SSE2-NEXT: movapd %xmm5, %xmm4489; SSE2-NEXT: maxpd %xmm1, %xmm4490; SSE2-NEXT: cmpunordpd %xmm1, %xmm1491; SSE2-NEXT: andpd %xmm1, %xmm5492; SSE2-NEXT: andnpd %xmm4, %xmm1493; SSE2-NEXT: orpd %xmm5, %xmm1494; SSE2-NEXT: movapd %xmm6, %xmm4495; SSE2-NEXT: maxpd %xmm2, %xmm4496; SSE2-NEXT: cmpunordpd %xmm2, %xmm2497; SSE2-NEXT: andpd %xmm2, %xmm6498; SSE2-NEXT: andnpd %xmm4, %xmm2499; SSE2-NEXT: orpd %xmm6, %xmm2500; SSE2-NEXT: movapd %xmm7, %xmm4501; SSE2-NEXT: maxpd %xmm3, %xmm4502; SSE2-NEXT: cmpunordpd %xmm3, %xmm3503; SSE2-NEXT: andpd %xmm3, %xmm7504; SSE2-NEXT: andnpd %xmm4, %xmm3505; SSE2-NEXT: orpd %xmm7, %xmm3506; SSE2-NEXT: retq507;508; SSE4-LABEL: test_intrinsic_fmax_v8f64:509; SSE4: # %bb.0:510; SSE4-NEXT: movapd %xmm3, %xmm11511; SSE4-NEXT: movapd %xmm2, %xmm10512; SSE4-NEXT: movapd %xmm1, %xmm9513; SSE4-NEXT: movapd %xmm4, %xmm8514; SSE4-NEXT: maxpd %xmm0, %xmm8515; SSE4-NEXT: cmpunordpd %xmm0, %xmm0516; SSE4-NEXT: blendvpd %xmm0, %xmm4, %xmm8517; SSE4-NEXT: movapd %xmm5, %xmm1518; SSE4-NEXT: maxpd %xmm9, %xmm1519; SSE4-NEXT: cmpunordpd %xmm9, %xmm9520; SSE4-NEXT: movapd %xmm9, %xmm0521; SSE4-NEXT: blendvpd %xmm0, %xmm5, %xmm1522; SSE4-NEXT: movapd %xmm6, %xmm2523; SSE4-NEXT: maxpd %xmm10, %xmm2524; SSE4-NEXT: cmpunordpd %xmm10, %xmm10525; SSE4-NEXT: movapd %xmm10, %xmm0526; SSE4-NEXT: blendvpd %xmm0, %xmm6, %xmm2527; SSE4-NEXT: movapd %xmm7, %xmm3528; SSE4-NEXT: maxpd %xmm11, %xmm3529; SSE4-NEXT: cmpunordpd %xmm11, %xmm11530; SSE4-NEXT: movapd %xmm11, %xmm0531; SSE4-NEXT: blendvpd %xmm0, %xmm7, %xmm3532; SSE4-NEXT: movapd %xmm8, %xmm0533; SSE4-NEXT: retq534;535; AVX1-LABEL: test_intrinsic_fmax_v8f64:536; AVX1: # %bb.0:537; AVX1-NEXT: vmaxpd %ymm0, %ymm2, %ymm4538; AVX1-NEXT: vcmpunordpd %ymm0, %ymm0, %ymm0539; AVX1-NEXT: vblendvpd %ymm0, %ymm2, %ymm4, %ymm0540; AVX1-NEXT: vmaxpd %ymm1, %ymm3, %ymm2541; AVX1-NEXT: vcmpunordpd %ymm1, %ymm1, %ymm1542; AVX1-NEXT: vblendvpd %ymm1, %ymm3, %ymm2, %ymm1543; AVX1-NEXT: retq544;545; AVX512-LABEL: test_intrinsic_fmax_v8f64:546; AVX512: # %bb.0:547; AVX512-NEXT: vmaxpd %zmm0, %zmm1, %zmm2548; AVX512-NEXT: vcmpunordpd %zmm0, %zmm0, %k1549; AVX512-NEXT: vmovapd %zmm1, %zmm2 {%k1}550; AVX512-NEXT: vmovapd %zmm2, %zmm0551; AVX512-NEXT: retq552 %z = call <8 x double> @llvm.maxnum.v8f64(<8 x double> %x, <8 x double> %y) readnone553 ret <8 x double> %z554}555 556; The IR-level FMF propagate to the node. With nnan, there's no need to blend.557 558define double @maxnum_intrinsic_nnan_fmf_f64(double %a, double %b) {559; SSE-LABEL: maxnum_intrinsic_nnan_fmf_f64:560; SSE: # %bb.0:561; SSE-NEXT: maxsd %xmm1, %xmm0562; SSE-NEXT: retq563;564; AVX-LABEL: maxnum_intrinsic_nnan_fmf_f64:565; AVX: # %bb.0:566; AVX-NEXT: vmaxsd %xmm1, %xmm0, %xmm0567; AVX-NEXT: retq568 %r = tail call nnan double @llvm.maxnum.f64(double %a, double %b)569 ret double %r570}571 572; Make sure vectors work too.573 574define <4 x float> @maxnum_intrinsic_nnan_fmf_f432(<4 x float> %a, <4 x float> %b) {575; SSE-LABEL: maxnum_intrinsic_nnan_fmf_f432:576; SSE: # %bb.0:577; SSE-NEXT: maxps %xmm1, %xmm0578; SSE-NEXT: retq579;580; AVX-LABEL: maxnum_intrinsic_nnan_fmf_f432:581; AVX: # %bb.0:582; AVX-NEXT: vmaxps %xmm1, %xmm0, %xmm0583; AVX-NEXT: retq584 %r = tail call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %a, <4 x float> %b)585 ret <4 x float> %r586}587 588; Current (but legacy someday): a function-level attribute should also enable the fold.589 590define float @maxnum_intrinsic_nnan_attr_f32(float %a, float %b) #0 {591; SSE-LABEL: maxnum_intrinsic_nnan_attr_f32:592; SSE: # %bb.0:593; SSE-NEXT: maxss %xmm1, %xmm0594; SSE-NEXT: retq595;596; AVX-LABEL: maxnum_intrinsic_nnan_attr_f32:597; AVX: # %bb.0:598; AVX-NEXT: vmaxss %xmm1, %xmm0, %xmm0599; AVX-NEXT: retq600 %r = tail call float @llvm.maxnum.f32(float %a, float %b)601 ret float %r602}603 604; Make sure vectors work too.605 606define <2 x double> @maxnum_intrinsic_nnan_attr_f64(<2 x double> %a, <2 x double> %b) #0 {607; SSE-LABEL: maxnum_intrinsic_nnan_attr_f64:608; SSE: # %bb.0:609; SSE-NEXT: maxpd %xmm1, %xmm0610; SSE-NEXT: retq611;612; AVX-LABEL: maxnum_intrinsic_nnan_attr_f64:613; AVX: # %bb.0:614; AVX-NEXT: vmaxpd %xmm1, %xmm0, %xmm0615; AVX-NEXT: retq616 %r = tail call <2 x double> @llvm.maxnum.v2f64(<2 x double> %a, <2 x double> %b)617 ret <2 x double> %r618}619 620define float @test_maxnum_const_op1(float %x) {621; SSE-LABEL: test_maxnum_const_op1:622; SSE: # %bb.0:623; SSE-NEXT: maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0624; SSE-NEXT: retq625;626; AVX-LABEL: test_maxnum_const_op1:627; AVX: # %bb.0:628; AVX-NEXT: vmaxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0629; AVX-NEXT: retq630 %r = call float @llvm.maxnum.f32(float 1.0, float %x)631 ret float %r632}633 634define float @test_maxnum_const_op2(float %x) {635; SSE-LABEL: test_maxnum_const_op2:636; SSE: # %bb.0:637; SSE-NEXT: maxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0638; SSE-NEXT: retq639;640; AVX-LABEL: test_maxnum_const_op2:641; AVX: # %bb.0:642; AVX-NEXT: vmaxss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0643; AVX-NEXT: retq644 %r = call float @llvm.maxnum.f32(float %x, float 1.0)645 ret float %r646}647 648define float @test_maxnum_const_nan(float %x, float %y) {649; SSE-LABEL: test_maxnum_const_nan:650; SSE: # %bb.0:651; SSE-NEXT: movaps %xmm1, %xmm0652; SSE-NEXT: retq653;654; AVX-LABEL: test_maxnum_const_nan:655; AVX: # %bb.0:656; AVX-NEXT: vmovaps %xmm1, %xmm0657; AVX-NEXT: retq658 %r = call float @llvm.maxnum.f32(float %y, float 0x7fff000000000000)659 ret float %r660}661 662; nnan maxnum(Y, -inf) -> Y663define float @test_maxnum_neg_inf_nnan(float %x, float %y) nounwind {664; SSE-LABEL: test_maxnum_neg_inf_nnan:665; SSE: # %bb.0:666; SSE-NEXT: movaps %xmm1, %xmm0667; SSE-NEXT: retq668;669; AVX-LABEL: test_maxnum_neg_inf_nnan:670; AVX: # %bb.0:671; AVX-NEXT: vmovaps %xmm1, %xmm0672; AVX-NEXT: retq673 %r = call nnan float @llvm.maxnum.f32(float %y, float 0xfff0000000000000)674 ret float %r675}676 677; Test SNaN quieting678define float @test_maxnum_snan(float %x) {679; SSE-LABEL: test_maxnum_snan:680; SSE: # %bb.0:681; SSE-NEXT: movss {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]682; SSE-NEXT: retq683;684; AVX-LABEL: test_maxnum_snan:685; AVX: # %bb.0:686; AVX-NEXT: vmovss {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]687; AVX-NEXT: retq688 %r = call float @llvm.maxnum.f32(float 0x7ff4000000000000, float %x)689 ret float %r690}691 692attributes #0 = { "no-nans-fp-math"="true" }693 694