1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
5 ; Check constrained detection of cases where negative zero is impossible:
8 define 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]]
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
20 define 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]]
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
32 define 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]]
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
44 define 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]]
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
56 ; NOTE: The fsub instruction is expected to remain, but the result isn't used.
57 define 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]]
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
70 ; NOTE: The fsub instruction is expected to remain, but the result isn't used.
71 define 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]]
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
84 ; Test all the rounding modes. Rounding mode and exception handling
87 define 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]]
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
99 define 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]]
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
111 define 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]]
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
123 define 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]]
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
135 define 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]]
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
147 define 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]]
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
159 define 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]]
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
171 define 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]]
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
183 define 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]]
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
195 define 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]]
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
207 declare float @llvm.experimental.constrained.sqrt.f32(float, metadata, metadata) #0
208 declare float @llvm.experimental.constrained.fsub.f32(float, float, metadata, metadata) #0
210 declare float @llvm.experimental.constrained.sitofp.f32.i32(i32, metadata, metadata) #0
211 declare float @llvm.experimental.constrained.uitofp.f32.i32(i32, metadata, metadata) #0
213 attributes #0 = { strictfp }