1 ; RUN: opt -S -dxil-intrinsic-expansion -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,EXPCHECK
\r
2 ; RUN: opt -S -dxil-intrinsic-expansion -scalarizer -dxil-op-lower -mtriple=dxil-pc-shadermodel6.3-library %s | FileCheck %s --check-prefixes=CHECK,DOPCHECK
\r
4 ; Make sure correct dxil expansions for atan2 are generated for float and half.
\r
6 define noundef float @atan2_float(float noundef %y, float noundef %x) {
\r
8 ; CHECK: [[DIV:%.+]] = fdiv float %y, %x
\r
9 ; EXPCHECK: [[ATAN:%.+]] = call float @llvm.atan.f32(float [[DIV]])
\r
10 ; DOPCHECK: [[ATAN:%.+]] = call float @dx.op.unary.f32(i32 17, float [[DIV]])
\r
11 ; CHECK-DAG: [[ADD_PI:%.+]] = fadd float [[ATAN]], 0x400921FB60000000
\r
12 ; CHECK-DAG: [[SUB_PI:%.+]] = fsub float [[ATAN]], 0x400921FB60000000
\r
13 ; CHECK-DAG: [[X_LT_0:%.+]] = fcmp olt float %x, 0.000000e+00
\r
14 ; CHECK-DAG: [[X_EQ_0:%.+]] = fcmp oeq float %x, 0.000000e+00
\r
15 ; CHECK-DAG: [[Y_GE_0:%.+]] = fcmp oge float %y, 0.000000e+00
\r
16 ; CHECK-DAG: [[Y_LT_0:%.+]] = fcmp olt float %y, 0.000000e+00
\r
17 ; CHECK: [[XLT0_AND_YGE0:%.+]] = and i1 [[X_LT_0]], [[Y_GE_0]]
\r
18 ; CHECK: [[SELECT_ADD_PI:%.+]] = select i1 [[XLT0_AND_YGE0]], float [[ADD_PI]], float [[ATAN]]
\r
19 ; CHECK: [[XLT0_AND_YLT0:%.+]] = and i1 [[X_LT_0]], [[Y_LT_0]]
\r
20 ; CHECK: [[SELECT_SUB_PI:%.+]] = select i1 [[XLT0_AND_YLT0]], float [[SUB_PI]], float [[SELECT_ADD_PI]]
\r
21 ; CHECK: [[XEQ0_AND_YLT0:%.+]] = and i1 [[X_EQ_0]], [[Y_LT_0]]
\r
22 ; CHECK: [[SELECT_NEGHPI:%.+]] = select i1 [[XEQ0_AND_YLT0]], float 0xBFF921FB60000000, float [[SELECT_SUB_PI]]
\r
23 ; CHECK: [[XEQ0_AND_YGE0:%.+]] = and i1 [[X_EQ_0]], [[Y_GE_0]]
\r
24 ; CHECK: [[SELECT_HPI:%.+]] = select i1 [[XEQ0_AND_YGE0]], float 0x3FF921FB60000000, float [[SELECT_NEGHPI]]
\r
25 ; CHECK: ret float [[SELECT_HPI]]
\r
26 %elt.atan2 = call float @llvm.atan2.f32(float %y, float %x)
\r
27 ret float %elt.atan2
\r
30 define noundef half @atan2_half(half noundef %y, half noundef %x) {
\r
32 ; CHECK: [[DIV:%.+]] = fdiv half %y, %x
\r
33 ; EXPCHECK: [[ATAN:%.+]] = call half @llvm.atan.f16(half [[DIV]])
\r
34 ; DOPCHECK: [[ATAN:%.+]] = call half @dx.op.unary.f16(i32 17, half [[DIV]])
\r
35 ; CHECK-DAG: [[ADD_PI:%.+]] = fadd half [[ATAN]], 0xH4248
\r
36 ; CHECK-DAG: [[SUB_PI:%.+]] = fsub half [[ATAN]], 0xH4248
\r
37 ; CHECK-DAG: [[X_LT_0:%.+]] = fcmp olt half %x, 0xH0000
\r
38 ; CHECK-DAG: [[X_EQ_0:%.+]] = fcmp oeq half %x, 0xH0000
\r
39 ; CHECK-DAG: [[Y_GE_0:%.+]] = fcmp oge half %y, 0xH0000
\r
40 ; CHECK-DAG: [[Y_LT_0:%.+]] = fcmp olt half %y, 0xH0000
\r
41 ; CHECK: [[XLT0_AND_YGE0:%.+]] = and i1 [[X_LT_0]], [[Y_GE_0]]
\r
42 ; CHECK: [[SELECT_ADD_PI:%.+]] = select i1 [[XLT0_AND_YGE0]], half [[ADD_PI]], half [[ATAN]]
\r
43 ; CHECK: [[XLT0_AND_YLT0:%.+]] = and i1 [[X_LT_0]], [[Y_LT_0]]
\r
44 ; CHECK: [[SELECT_SUB_PI:%.+]] = select i1 [[XLT0_AND_YLT0]], half [[SUB_PI]], half [[SELECT_ADD_PI]]
\r
45 ; CHECK: [[XEQ0_AND_YLT0:%.+]] = and i1 [[X_EQ_0]], [[Y_LT_0]]
\r
46 ; CHECK: [[SELECT_NEGHPI:%.+]] = select i1 [[XEQ0_AND_YLT0]], half 0xHBE48, half [[SELECT_SUB_PI]]
\r
47 ; CHECK: [[XEQ0_AND_YGE0:%.+]] = and i1 [[X_EQ_0]], [[Y_GE_0]]
\r
48 ; CHECK: [[SELECT_HPI:%.+]] = select i1 [[XEQ0_AND_YGE0]], half 0xH3E48, half [[SELECT_NEGHPI]]
\r
49 ; CHECK: ret half [[SELECT_HPI]]
\r
50 %elt.atan2 = call half @llvm.atan2.f16(half %y, half %x)
\r
54 define noundef <4 x float> @atan2_float4(<4 x float> noundef %y, <4 x float> noundef %x) {
\r
56 ; Just Expansion, no scalarization or lowering:
\r
57 ; EXPCHECK: [[DIV:%.+]] = fdiv <4 x float> %y, %x
\r
58 ; EXPCHECK: [[ATAN:%.+]] = call <4 x float> @llvm.atan.v4f32(<4 x float> [[DIV]])
\r
59 ; EXPCHECK-DAG: [[ADD_PI:%.+]] = fadd <4 x float> [[ATAN]], splat (float 0x400921FB60000000)
\r
60 ; EXPCHECK-DAG: [[SUB_PI:%.+]] = fsub <4 x float> [[ATAN]], splat (float 0x400921FB60000000)
\r
61 ; EXPCHECK-DAG: [[X_LT_0:%.+]] = fcmp olt <4 x float> %x, zeroinitializer
\r
62 ; EXPCHECK-DAG: [[X_EQ_0:%.+]] = fcmp oeq <4 x float> %x, zeroinitializer
\r
63 ; EXPCHECK-DAG: [[Y_GE_0:%.+]] = fcmp oge <4 x float> %y, zeroinitializer
\r
64 ; EXPCHECK-DAG: [[Y_LT_0:%.+]] = fcmp olt <4 x float> %y, zeroinitializer
\r
65 ; EXPCHECK: [[XLT0_AND_YGE0:%.+]] = and <4 x i1> [[X_LT_0]], [[Y_GE_0]]
\r
66 ; EXPCHECK: [[SELECT_ADD_PI:%.+]] = select <4 x i1> [[XLT0_AND_YGE0]], <4 x float> [[ADD_PI]], <4 x float> [[ATAN]]
\r
67 ; EXPCHECK: [[XLT0_AND_YLT0:%.+]] = and <4 x i1> [[X_LT_0]], [[Y_LT_0]]
\r
68 ; EXPCHECK: [[SELECT_SUB_PI:%.+]] = select <4 x i1> [[XLT0_AND_YLT0]], <4 x float> [[SUB_PI]], <4 x float> [[SELECT_ADD_PI]]
\r
69 ; EXPCHECK: [[XEQ0_AND_YLT0:%.+]] = and <4 x i1> [[X_EQ_0]], [[Y_LT_0]]
\r
70 ; EXPCHECK: [[SELECT_NEGHPI:%.+]] = select <4 x i1> [[XEQ0_AND_YLT0]], <4 x float> splat (float 0xBFF921FB60000000), <4 x float> [[SELECT_SUB_PI]]
\r
71 ; EXPCHECK: [[XEQ0_AND_YGE0:%.+]] = and <4 x i1> [[X_EQ_0]], [[Y_GE_0]]
\r
72 ; EXPCHECK: [[SELECT_HPI:%.+]] = select <4 x i1> [[XEQ0_AND_YGE0]], <4 x float> splat (float 0x3FF921FB60000000), <4 x float> [[SELECT_NEGHPI]]
\r
73 ; EXPCHECK: ret <4 x float> [[SELECT_HPI]]
\r
75 ; Scalarization occurs after expansion, so atan scalarization is tested separately.
\r
76 ; Expansion, scalarization and lowering:
\r
77 ; Just make sure this expands to exactly 4 scalar DXIL atan (OpCode=17) calls.
\r
78 ; DOPCHECK-COUNT-4: call float @dx.op.unary.f32(i32 17, float %{{.*}})
\r
79 ; DOPCHECK-NOT: call float @dx.op.unary.f32(i32 17,
\r
81 %elt.atan2 = call <4 x float> @llvm.atan2.v4f32(<4 x float> %y, <4 x float> %x)
\r
82 ret <4 x float> %elt.atan2
\r
85 declare half @llvm.atan2.f16(half, half)
\r
86 declare float @llvm.atan2.f32(float, float)
\r
87 declare <4 x float> @llvm.atan2.v4f32(<4 x float>, <4 x float>)
\r