Skip to content

Commit 6b3220a

Browse files
authored
[InstCombine] Avoid crash on aggregate types in SimplifyDemandedUseFPClass (#111128)
The disables folding for FP aggregates that are not poison/posZero types, which is currently not supported. Note: To fully handle this aggregates would also likely require teaching `computeKnownFPClass()` to handle array and struct constants (which does not seem implemented outside of zero init).
1 parent d205191 commit 6b3220a

File tree

2 files changed

+130
-4
lines changed

2 files changed

+130
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1919,17 +1919,23 @@ Value *InstCombinerImpl::SimplifyDemandedVectorElts(Value *V,
19191919
/// For floating-point classes that resolve to a single bit pattern, return that
19201920
/// value.
19211921
static Constant *getFPClassConstant(Type *Ty, FPClassTest Mask) {
1922+
if (Mask == fcNone)
1923+
return PoisonValue::get(Ty);
1924+
1925+
if (Mask == fcPosZero)
1926+
return Constant::getNullValue(Ty);
1927+
1928+
// TODO: Support aggregate types that are allowed by FPMathOperator.
1929+
if (Ty->isAggregateType())
1930+
return nullptr;
1931+
19221932
switch (Mask) {
1923-
case fcPosZero:
1924-
return ConstantFP::getZero(Ty);
19251933
case fcNegZero:
19261934
return ConstantFP::getZero(Ty, true);
19271935
case fcPosInf:
19281936
return ConstantFP::getInfinity(Ty);
19291937
case fcNegInf:
19301938
return ConstantFP::getInfinity(Ty, true);
1931-
case fcNone:
1932-
return PoisonValue::get(Ty);
19331939
default:
19341940
return nullptr;
19351941
}

llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,126 @@ define nofpclass(inf) float @ret_nofpclass_inf__ninf() {
9191
ret float 0xFFF0000000000000
9292
}
9393

94+
; Basic aggregate tests to ensure this does not crash.
95+
define nofpclass(nan) { float } @ret_nofpclass_struct_ty() {
96+
; CHECK-LABEL: define nofpclass(nan) { float } @ret_nofpclass_struct_ty() {
97+
; CHECK-NEXT: entry:
98+
; CHECK-NEXT: ret { float } zeroinitializer
99+
;
100+
entry:
101+
ret { float } zeroinitializer
102+
}
103+
104+
define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() {
105+
; CHECK-LABEL: define nofpclass(nan) { float, float } @ret_nofpclass_multiple_elems_struct_ty() {
106+
; CHECK-NEXT: entry:
107+
; CHECK-NEXT: ret { float, float } zeroinitializer
108+
;
109+
entry:
110+
ret { float, float } zeroinitializer
111+
}
112+
113+
define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() {
114+
; CHECK-LABEL: define nofpclass(nan) { <4 x float>, <4 x float> } @ret_nofpclass_vector_elems_struct_ty() {
115+
; CHECK-NEXT: entry:
116+
; CHECK-NEXT: ret { <4 x float>, <4 x float> } zeroinitializer
117+
;
118+
entry:
119+
ret { <4 x float>, <4 x float> } zeroinitializer
120+
}
121+
122+
define nofpclass(nan) [ 5 x float ] @ret_nofpclass_array_ty() {
123+
; CHECK-LABEL: define nofpclass(nan) [5 x float] @ret_nofpclass_array_ty() {
124+
; CHECK-NEXT: entry:
125+
; CHECK-NEXT: ret [5 x float] zeroinitializer
126+
;
127+
entry:
128+
ret [ 5 x float ] zeroinitializer
129+
}
130+
131+
define nofpclass(nan) [ 2 x [ 5 x float ]] @ret_nofpclass_nested_array_ty() {
132+
; CHECK-LABEL: define nofpclass(nan) [2 x [5 x float]] @ret_nofpclass_nested_array_ty() {
133+
; CHECK-NEXT: entry:
134+
; CHECK-NEXT: ret [2 x [5 x float]] zeroinitializer
135+
;
136+
entry:
137+
ret [ 2 x [ 5 x float ]] zeroinitializer
138+
}
139+
140+
define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() {
141+
; CHECK-LABEL: define nofpclass(pinf) { float } @ret_nofpclass_struct_ty_pinf__ninf() {
142+
; CHECK-NEXT: entry:
143+
; CHECK-NEXT: ret { float } { float 0xFFF0000000000000 }
144+
;
145+
entry:
146+
ret { float } { float 0xFFF0000000000000 }
147+
}
148+
149+
define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() {
150+
; CHECK-LABEL: define nofpclass(pinf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pinf__ninf() {
151+
; CHECK-NEXT: entry:
152+
; CHECK-NEXT: ret { float, float } { float 0xFFF0000000000000, float 0xFFF0000000000000 }
153+
;
154+
entry:
155+
ret { float, float } { float 0xFFF0000000000000, float 0xFFF0000000000000 }
156+
}
157+
158+
define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() {
159+
; CHECK-LABEL: define nofpclass(pinf) { <2 x float> } @ret_nofpclass_vector_elems_struct_ty_pinf__ninf() {
160+
; CHECK-NEXT: entry:
161+
; CHECK-NEXT: ret { <2 x float> } { <2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000> }
162+
;
163+
entry:
164+
ret { <2 x float>} { <2 x float> <float 0xFFF0000000000000, float 0xFFF0000000000000> }
165+
}
166+
167+
define nofpclass(pinf) [ 1 x [ 1 x float ]] @ret_nofpclass_nested_array_ty_pinf__ninf() {
168+
; CHECK-LABEL: @ret_nofpclass_nested_array_ty_pinf__ninf() {
169+
; CHECK-NEXT: entry:
170+
; CHECK-NEXT: ret {{.*}}float 0xFFF0000000000000
171+
;
172+
entry:
173+
ret [ 1 x [ 1 x float ]] [[ 1 x float ] [float 0xFFF0000000000000]]
174+
}
175+
176+
define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() {
177+
; CHECK-LABEL: define nofpclass(pzero) { float, float } @ret_nofpclass_multiple_elems_struct_ty_pzero__nzero() {
178+
; CHECK-NEXT: entry:
179+
; CHECK-NEXT: ret { float, float } { float -0.000000e+00, float -0.000000e+00 }
180+
;
181+
entry:
182+
ret { float, float } { float -0.0, float -0.0 }
183+
}
184+
185+
define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() {
186+
; CHECK-LABEL: define nofpclass(ninf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_ninf__npinf() {
187+
; CHECK-NEXT: entry:
188+
; CHECK-NEXT: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }
189+
;
190+
entry:
191+
ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }
192+
}
193+
194+
; FIXME (should be poison): Support computeKnownFPClass() for non-zero aggregates.
195+
define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() {
196+
; CHECK-LABEL: define nofpclass(inf) { float, float } @ret_nofpclass_multiple_elems_struct_ty_inf__npinf() {
197+
; CHECK-NEXT: entry:
198+
; CHECK-NEXT: ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }
199+
;
200+
entry:
201+
ret { float, float } { float 0x7FF0000000000000, float 0x7FF0000000000000 }
202+
}
203+
204+
; FIXME (should be poison): Support computeKnownFPClass() for non-zero aggregates.
205+
define nofpclass(nzero) [ 1 x float ] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() {
206+
; CHECK-LABEL: define nofpclass(nzero) [1 x float] @ret_nofpclass_multiple_elems_struct_ty_nzero_nzero() {
207+
; CHECK-NEXT: entry:
208+
; CHECK-NEXT: ret [1 x float] [float -0.000000e+00]
209+
;
210+
entry:
211+
ret [ 1 x float ] [ float -0.0 ]
212+
}
213+
94214
; Negative test, do nothing
95215
define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_inf_lhs(i1 %cond, float nofpclass(inf) %x, float %y) {
96216
; CHECK-LABEL: define nofpclass(inf) float @ret_nofpclass_inf__select_nofpclass_inf_lhs

0 commit comments

Comments
 (0)