xref: /llvm-project/llvm/test/Transforms/InstSimplify/strictfp-sqrt-nonneg.ll (revision c21f1feed390a818458ebd069424ca80b0e4dfd5)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
3
4;
5; Check constrained detection of cases where negative zero is impossible:
6;
7
8define float @nonneg_u_defaultenv(i32 %a) #0 {
9; CHECK-LABEL: @nonneg_u_defaultenv(
10; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0:[0-9]+]]
11; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
12; CHECK-NEXT:    ret float [[SQRA]]
13;
14  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
15  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
16  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
17  ret float %sub
18}
19
20define float @nonneg_s_defaultenv(i32 %a) #0 {
21; CHECK-LABEL: @nonneg_s_defaultenv(
22; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
23; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.ignore") #[[ATTR0]]
24; CHECK-NEXT:    ret float [[SQRA]]
25;
26  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
27  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
28  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.ignore") #0
29  ret float %sub
30}
31
32define float @nonneg_u_maytrap(i32 %a) #0 {
33; CHECK-LABEL: @nonneg_u_maytrap(
34; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
35; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
36; CHECK-NEXT:    ret float [[SQRA]]
37;
38  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
39  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
40  %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
41  ret float %sub
42}
43
44define float @nonneg_s_maytrap(i32 %a) #0 {
45; CHECK-LABEL: @nonneg_s_maytrap(
46; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
47; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.maytrap") #[[ATTR0]]
48; CHECK-NEXT:    ret float [[SQRA]]
49;
50  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
51  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
52  %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.maytrap") #0
53  ret float %sub
54}
55
56; NOTE: The fsub instruction is expected to remain, but the result isn't used.
57define float @nonneg_u_ebstrict(i32 %a) #0 {
58; CHECK-LABEL: @nonneg_u_ebstrict(
59; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
60; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
61; CHECK-NEXT:    [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[SQRA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
62; CHECK-NEXT:    ret float [[SQRA]]
63;
64  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
65  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
66  %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
67  ret float %sub
68}
69
70; NOTE: The fsub instruction is expected to remain, but the result isn't used.
71define float @nonneg_s_ebstrict(i32 %a) #0 {
72; CHECK-LABEL: @nonneg_s_ebstrict(
73; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
74; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
75; CHECK-NEXT:    [[SUB:%.*]] = call nnan float @llvm.experimental.constrained.fsub.f32(float [[SQRA]], float -0.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]]
76; CHECK-NEXT:    ret float [[SQRA]]
77;
78  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
79  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
80  %sub = call nnan float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearest", metadata !"fpexcept.strict") #0
81  ret float %sub
82}
83
84; Test all the rounding modes. Rounding mode and exception handling
85; shouldn't matter.
86
87define float @nonneg_u_downward(i32 %a) #0 {
88; CHECK-LABEL: @nonneg_u_downward(
89; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
90; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
91; CHECK-NEXT:    ret float [[SQRA]]
92;
93  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.downward", metadata !"fpexcept.ignore") #0
94  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.downward", metadata !"fpexcept.ignore") #0
95  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.downward", metadata !"fpexcept.ignore") #0
96  ret float %sub
97}
98
99define float @nonneg_s_downward(i32 %a) #0 {
100; CHECK-LABEL: @nonneg_s_downward(
101; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
102; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.downward", metadata !"fpexcept.ignore") #[[ATTR0]]
103; CHECK-NEXT:    ret float [[SQRA]]
104;
105  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.downward", metadata !"fpexcept.ignore") #0
106  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.downward", metadata !"fpexcept.ignore") #0
107  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.downward", metadata !"fpexcept.ignore") #0
108  ret float %sub
109}
110
111define float @nonneg_u_upward(i32 %a) #0 {
112; CHECK-LABEL: @nonneg_u_upward(
113; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.upward", metadata !"fpexcept.ignore") #[[ATTR0]]
114; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.upward", metadata !"fpexcept.ignore") #[[ATTR0]]
115; CHECK-NEXT:    ret float [[SQRA]]
116;
117  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.upward", metadata !"fpexcept.ignore") #0
118  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.upward", metadata !"fpexcept.ignore") #0
119  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.upward", metadata !"fpexcept.ignore") #0
120  ret float %sub
121}
122
123define float @nonneg_s_upward(i32 %a) #0 {
124; CHECK-LABEL: @nonneg_s_upward(
125; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.upward", metadata !"fpexcept.ignore") #[[ATTR0]]
126; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.upward", metadata !"fpexcept.ignore") #[[ATTR0]]
127; CHECK-NEXT:    ret float [[SQRA]]
128;
129  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.upward", metadata !"fpexcept.ignore") #0
130  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.upward", metadata !"fpexcept.ignore") #0
131  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.upward", metadata !"fpexcept.ignore") #0
132  ret float %sub
133}
134
135define float @nonneg_u_towardzero(i32 %a) #0 {
136; CHECK-LABEL: @nonneg_u_towardzero(
137; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.towardzero", metadata !"fpexcept.ignore") #[[ATTR0]]
138; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.towardzero", metadata !"fpexcept.ignore") #[[ATTR0]]
139; CHECK-NEXT:    ret float [[SQRA]]
140;
141  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
142  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
143  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
144  ret float %sub
145}
146
147define float @nonneg_s_towardzero(i32 %a) #0 {
148; CHECK-LABEL: @nonneg_s_towardzero(
149; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.towardzero", metadata !"fpexcept.ignore") #[[ATTR0]]
150; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.towardzero", metadata !"fpexcept.ignore") #[[ATTR0]]
151; CHECK-NEXT:    ret float [[SQRA]]
152;
153  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
154  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
155  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.towardzero", metadata !"fpexcept.ignore") #0
156  ret float %sub
157}
158
159define float @nonneg_u_tonearestaway(i32 %a) #0 {
160; CHECK-LABEL: @nonneg_u_tonearestaway(
161; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #[[ATTR0]]
162; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #[[ATTR0]]
163; CHECK-NEXT:    ret float [[SQRA]]
164;
165  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
166  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
167  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
168  ret float %sub
169}
170
171define float @nonneg_s_tonearestaway(i32 %a) #0 {
172; CHECK-LABEL: @nonneg_s_tonearestaway(
173; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #[[ATTR0]]
174; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #[[ATTR0]]
175; CHECK-NEXT:    ret float [[SQRA]]
176;
177  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
178  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
179  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.tonearestaway", metadata !"fpexcept.ignore") #0
180  ret float %sub
181}
182
183define float @nonneg_u_dynamic(i32 %a) #0 {
184; CHECK-LABEL: @nonneg_u_dynamic(
185; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
186; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
187; CHECK-NEXT:    ret float [[SQRA]]
188;
189  %fpa = call float @llvm.experimental.constrained.uitofp.f32.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
190  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
191  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
192  ret float %sub
193}
194
195define float @nonneg_s_dynamic(i32 %a) #0 {
196; CHECK-LABEL: @nonneg_s_dynamic(
197; CHECK-NEXT:    [[FPA:%.*]] = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 [[A:%.*]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
198; CHECK-NEXT:    [[SQRA:%.*]] = call float @llvm.experimental.constrained.sqrt.f32(float [[FPA]], metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]]
199; CHECK-NEXT:    ret float [[SQRA]]
200;
201  %fpa = call float @llvm.experimental.constrained.sitofp.f32.i32(i32 %a, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
202  %sqra = call float @llvm.experimental.constrained.sqrt.f32(float %fpa, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
203  %sub = call float @llvm.experimental.constrained.fsub.f32(float %sqra, float -0.0, metadata !"round.dynamic", metadata !"fpexcept.ignore") #0
204  ret float %sub
205}
206
207declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) #0
208declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) #0
209
210declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) #0
211declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata) #0
212
213attributes #0 = { strictfp }
214