1; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=sse2 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=SSE 2; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=avx < %s | FileCheck %s --check-prefix=CHECK --check-prefix=AVX 3 4declare float @fmaxf(float, float) 5declare double @fmax(double, double) 6declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) 7declare float @llvm.maxnum.f32(float, float) 8declare double @llvm.maxnum.f64(double, double) 9declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) 10 11declare <2 x float> @llvm.maxnum.v2f32(<2 x float>, <2 x float>) 12declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>) 13declare <2 x double> @llvm.maxnum.v2f64(<2 x double>, <2 x double>) 14declare <4 x double> @llvm.maxnum.v4f64(<4 x double>, <4 x double>) 15declare <8 x double> @llvm.maxnum.v8f64(<8 x double>, <8 x double>) 16 17 18; CHECK-LABEL: @test_fmaxf 19; CHECK: jmp fmaxf 20define float @test_fmaxf(float %x, float %y) { 21 %z = call float @fmaxf(float %x, float %y) readnone 22 ret float %z 23} 24 25; CHECK-LABEL: @test_fmax 26; CHECK: jmp fmax 27define double @test_fmax(double %x, double %y) { 28 %z = call double @fmax(double %x, double %y) readnone 29 ret double %z 30} 31 32; CHECK-LABEL: @test_fmaxl 33; CHECK: callq fmaxl 34define x86_fp80 @test_fmaxl(x86_fp80 %x, x86_fp80 %y) { 35 %z = call x86_fp80 @fmaxl(x86_fp80 %x, x86_fp80 %y) readnone 36 ret x86_fp80 %z 37} 38 39; CHECK-LABEL: @test_intrinsic_fmaxf 40; CHECK: jmp fmaxf 41define float @test_intrinsic_fmaxf(float %x, float %y) { 42 %z = call float @llvm.maxnum.f32(float %x, float %y) readnone 43 ret float %z 44} 45 46; CHECK-LABEL: @test_intrinsic_fmax 47; CHECK: jmp fmax 48define double @test_intrinsic_fmax(double %x, double %y) { 49 %z = call double @llvm.maxnum.f64(double %x, double %y) readnone 50 ret double %z 51} 52 53; CHECK-LABEL: @test_intrinsic_fmaxl 54; CHECK: callq fmaxl 55define x86_fp80 @test_intrinsic_fmaxl(x86_fp80 %x, x86_fp80 %y) { 56 %z = call x86_fp80 @llvm.maxnum.f80(x86_fp80 %x, x86_fp80 %y) readnone 57 ret x86_fp80 %z 58} 59 60; CHECK-LABEL: @test_intrinsic_fmax_v2f32 61; SSE: movaps %xmm1, {{[0-9]+}}(%rsp) # 16-byte Spill 62; SSE-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 63; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1,2,3] 64; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,1,2,3] 65; SSE-NEXT: callq fmaxf 66; SSE-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 67; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 68; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,2,3] 69; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 70; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,1,2,3] 71; SSE-NEXT: callq fmaxf 72; SSE-NEXT: unpcklps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 73; SSE: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 74; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 75; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 76; SSE-NEXT: callq fmaxf 77; SSE-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 78; SSE-NEXT: movapd {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 79; SSE-NEXT: shufpd {{.*#+}} xmm0 = xmm0[1,0] 80; SSE-NEXT: movapd {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 81; SSE-NEXT: shufpd {{.*#+}} xmm1 = xmm1[1,0] 82; SSE-NEXT: callq fmaxf 83; SSE-NEXT: movaps (%rsp), %xmm1 # 16-byte Reload 84; SSE-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 85; SSE-NEXT: unpcklps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 86; SSE: movaps %xmm1, %xmm0 87; SSE-NEXT: addq $72, %rsp 88; SSE-NEXT: retq 89; 90; AVX: vmovaps %xmm1, {{[0-9]+}}(%rsp) # 16-byte Spill 91; AVX-NEXT: vmovaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 92; AVX-NEXT: callq fmaxf 93; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 94; AVX-NEXT: vmovshdup {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 95; AVX: vmovshdup {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 96; AVX: callq fmaxf 97; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 98; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[2,3] 99; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 100; AVX-NEXT: vpermilpd $1, {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 101; AVX: vpermilpd $1, {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 102; AVX: callq fmaxf 103; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 104; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0],xmm1[3] 105; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 106; AVX-NEXT: vpermilps $231, {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 107; AVX: vpermilps $231, {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 108; AVX: callq fmaxf 109; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 110; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] 111; AVX-NEXT: addq $56, %rsp 112; AVX-NEXT: retq 113define <2 x float> @test_intrinsic_fmax_v2f32(<2 x float> %x, <2 x float> %y) { 114 %z = call <2 x float> @llvm.maxnum.v2f32(<2 x float> %x, <2 x float> %y) readnone 115 ret <2 x float> %z 116} 117 118; CHECK-LABEL: @test_intrinsic_fmax_v4f32 119; SSE: movaps %xmm1, {{[0-9]+}}(%rsp) # 16-byte Spill 120; SSE-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 121; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[3,1,2,3] 122; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[3,1,2,3] 123; SSE-NEXT: callq fmaxf 124; SSE-NEXT: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 125; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 126; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[1,1,2,3] 127; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 128; SSE-NEXT: shufps {{.*#+}} xmm1 = xmm1[1,1,2,3] 129; SSE-NEXT: callq fmaxf 130; SSE-NEXT: unpcklps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 131; SSE: movaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 132; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 133; SSE-NEXT: movaps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 134; SSE-NEXT: callq fmaxf 135; SSE-NEXT: movaps %xmm0, (%rsp) # 16-byte Spill 136; SSE-NEXT: movapd {{[0-9]+}}(%rsp), %xmm0 # 16-byte Reload 137; SSE-NEXT: shufpd {{.*#+}} xmm0 = xmm0[1,0] 138; SSE-NEXT: movapd {{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload 139; SSE-NEXT: shufpd {{.*#+}} xmm1 = xmm1[1,0] 140; SSE-NEXT: callq fmaxf 141; SSE-NEXT: movaps (%rsp), %xmm1 # 16-byte Reload 142; SSE-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] 143; SSE-NEXT: unpcklps {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 144; SSE: movaps %xmm1, %xmm0 145; SSE-NEXT: addq $72, %rsp 146; SSE-NEXT: retq 147; 148; AVX: vmovaps %xmm1, {{[0-9]+}}(%rsp) # 16-byte Spill 149; AVX-NEXT: vmovaps %xmm0, {{[0-9]+}}(%rsp) # 16-byte Spill 150; AVX-NEXT: callq fmaxf 151; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 152; AVX-NEXT: vmovshdup {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 153; AVX: vmovshdup {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 154; AVX: callq fmaxf 155; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 156; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0],xmm0[0],xmm1[2,3] 157; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 158; AVX-NEXT: vpermilpd $1, {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 159; AVX: vpermilpd $1, {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 160; AVX: callq fmaxf 161; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 162; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0],xmm1[3] 163; AVX-NEXT: vmovaps %xmm0, (%rsp) # 16-byte Spill 164; AVX-NEXT: vpermilps $231, {{[0-9]+}}(%rsp), %xmm0 # 16-byte Folded Reload 165; AVX: vpermilps $231, {{[0-9]+}}(%rsp), %xmm1 # 16-byte Folded Reload 166; AVX: callq fmaxf 167; AVX-NEXT: vmovaps (%rsp), %xmm1 # 16-byte Reload 168; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm1[0,1,2],xmm0[0] 169; AVX-NEXT: addq $56, %rsp 170; AVX-NEXT: retq 171define <4 x float> @test_intrinsic_fmax_v4f32(<4 x float> %x, <4 x float> %y) { 172 %z = call <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y) readnone 173 ret <4 x float> %z 174} 175 176; CHECK-LABEL: @test_intrinsic_fmax_v2f64 177; CHECK: callq fmax 178; CHECK: callq fmax 179define <2 x double> @test_intrinsic_fmax_v2f64(<2 x double> %x, <2 x double> %y) { 180 %z = call <2 x double> @llvm.maxnum.v2f64(<2 x double> %x, <2 x double> %y) readnone 181 ret <2 x double> %z 182} 183 184; CHECK-LABEL: @test_intrinsic_fmax_v4f64 185; CHECK: callq fmax 186; CHECK: callq fmax 187; CHECK: callq fmax 188; CHECK: callq fmax 189define <4 x double> @test_intrinsic_fmax_v4f64(<4 x double> %x, <4 x double> %y) { 190 %z = call <4 x double> @llvm.maxnum.v4f64(<4 x double> %x, <4 x double> %y) readnone 191 ret <4 x double> %z 192} 193 194; CHECK-LABEL: @test_intrinsic_fmax_v8f64 195; CHECK: callq fmax 196; CHECK: callq fmax 197; CHECK: callq fmax 198; CHECK: callq fmax 199; CHECK: callq fmax 200; CHECK: callq fmax 201; CHECK: callq fmax 202; CHECK: callq fmax 203define <8 x double> @test_intrinsic_fmax_v8f64(<8 x double> %x, <8 x double> %y) { 204 %z = call <8 x double> @llvm.maxnum.v8f64(<8 x double> %x, <8 x double> %y) readnone 205 ret <8 x double> %z 206} 207 208