Skip to content

Commit 9b1e953

Browse files
committed
[InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X transforms
As noted here https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html and by alive2, this transform isn't valid. If X is poison this potentially propagates poison when it shouldn't. This same transform still exists in DAGCombiner. Differential Revision: https://reviews.llvm.org/D83360
1 parent 0b39d2d commit 9b1e953

File tree

4 files changed

+96
-13
lines changed

4 files changed

+96
-13
lines changed

clang/test/CodeGen/arm-mve-intrinsics/dup.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ uint32x4_t test_vdupq_m_n_u32(uint32x4_t inactive, uint32_t a, mve_pred16_t p)
242242
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
243243
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x half> undef, half [[A:%.*]], i32 0
244244
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x half> [[DOTSPLATINSERT]], <8 x half> undef, <8 x i32> zeroinitializer
245-
// CHECK-NEXT: ret <8 x half> [[DOTSPLAT]]
245+
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x half> [[DOTSPLAT]], <8 x half> undef
246+
// CHECK-NEXT: ret <8 x half> [[TMP2]]
246247
//
247248
float16x8_t test_vdupq_x_n_f16(float16_t a, mve_pred16_t p)
248249
{
@@ -255,7 +256,8 @@ float16x8_t test_vdupq_x_n_f16(float16_t a, mve_pred16_t p)
255256
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
256257
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x float> undef, float [[A:%.*]], i32 0
257258
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x float> [[DOTSPLATINSERT]], <4 x float> undef, <4 x i32> zeroinitializer
258-
// CHECK-NEXT: ret <4 x float> [[DOTSPLAT]]
259+
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x float> [[DOTSPLAT]], <4 x float> undef
260+
// CHECK-NEXT: ret <4 x float> [[TMP2]]
259261
//
260262
float32x4_t test_vdupq_x_n_f32(float32_t a, mve_pred16_t p)
261263
{
@@ -268,7 +270,8 @@ float32x4_t test_vdupq_x_n_f32(float32_t a, mve_pred16_t p)
268270
// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]])
269271
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i32 0
270272
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <16 x i8> [[DOTSPLATINSERT]], <16 x i8> undef, <16 x i32> zeroinitializer
271-
// CHECK-NEXT: ret <16 x i8> [[DOTSPLAT]]
273+
// CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP1]], <16 x i8> [[DOTSPLAT]], <16 x i8> undef
274+
// CHECK-NEXT: ret <16 x i8> [[TMP2]]
272275
//
273276
int8x16_t test_vdupq_x_n_s8(int8_t a, mve_pred16_t p)
274277
{
@@ -281,7 +284,8 @@ int8x16_t test_vdupq_x_n_s8(int8_t a, mve_pred16_t p)
281284
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
282285
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i32 0
283286
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i16> [[DOTSPLATINSERT]], <8 x i16> undef, <8 x i32> zeroinitializer
284-
// CHECK-NEXT: ret <8 x i16> [[DOTSPLAT]]
287+
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[DOTSPLAT]], <8 x i16> undef
288+
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
285289
//
286290
int16x8_t test_vdupq_x_n_s16(int16_t a, mve_pred16_t p)
287291
{
@@ -294,7 +298,8 @@ int16x8_t test_vdupq_x_n_s16(int16_t a, mve_pred16_t p)
294298
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
295299
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i32 0
296300
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> undef, <4 x i32> zeroinitializer
297-
// CHECK-NEXT: ret <4 x i32> [[DOTSPLAT]]
301+
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[DOTSPLAT]], <4 x i32> undef
302+
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
298303
//
299304
int32x4_t test_vdupq_x_n_s32(int32_t a, mve_pred16_t p)
300305
{
@@ -307,7 +312,8 @@ int32x4_t test_vdupq_x_n_s32(int32_t a, mve_pred16_t p)
307312
// CHECK-NEXT: [[TMP1:%.*]] = call <16 x i1> @llvm.arm.mve.pred.i2v.v16i1(i32 [[TMP0]])
308313
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i32 0
309314
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <16 x i8> [[DOTSPLATINSERT]], <16 x i8> undef, <16 x i32> zeroinitializer
310-
// CHECK-NEXT: ret <16 x i8> [[DOTSPLAT]]
315+
// CHECK-NEXT: [[TMP2:%.*]] = select <16 x i1> [[TMP1]], <16 x i8> [[DOTSPLAT]], <16 x i8> undef
316+
// CHECK-NEXT: ret <16 x i8> [[TMP2]]
311317
//
312318
uint8x16_t test_vdupq_x_n_u8(uint8_t a, mve_pred16_t p)
313319
{
@@ -320,7 +326,8 @@ uint8x16_t test_vdupq_x_n_u8(uint8_t a, mve_pred16_t p)
320326
// CHECK-NEXT: [[TMP1:%.*]] = call <8 x i1> @llvm.arm.mve.pred.i2v.v8i1(i32 [[TMP0]])
321327
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i16> undef, i16 [[A:%.*]], i32 0
322328
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i16> [[DOTSPLATINSERT]], <8 x i16> undef, <8 x i32> zeroinitializer
323-
// CHECK-NEXT: ret <8 x i16> [[DOTSPLAT]]
329+
// CHECK-NEXT: [[TMP2:%.*]] = select <8 x i1> [[TMP1]], <8 x i16> [[DOTSPLAT]], <8 x i16> undef
330+
// CHECK-NEXT: ret <8 x i16> [[TMP2]]
324331
//
325332
uint16x8_t test_vdupq_x_n_u16(uint16_t a, mve_pred16_t p)
326333
{
@@ -333,7 +340,8 @@ uint16x8_t test_vdupq_x_n_u16(uint16_t a, mve_pred16_t p)
333340
// CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]])
334341
// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <4 x i32> undef, i32 [[A:%.*]], i32 0
335342
// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <4 x i32> [[DOTSPLATINSERT]], <4 x i32> undef, <4 x i32> zeroinitializer
336-
// CHECK-NEXT: ret <4 x i32> [[DOTSPLAT]]
343+
// CHECK-NEXT: [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i32> [[DOTSPLAT]], <4 x i32> undef
344+
// CHECK-NEXT: ret <4 x i32> [[TMP2]]
337345
//
338346
uint32x4_t test_vdupq_x_n_u32(uint32_t a, mve_pred16_t p)
339347
{

llvm/lib/Analysis/InstructionSimplify.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4118,11 +4118,6 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
41184118
if (TrueVal == FalseVal)
41194119
return TrueVal;
41204120

4121-
if (isa<UndefValue>(TrueVal)) // select ?, undef, X -> X
4122-
return FalseVal;
4123-
if (isa<UndefValue>(FalseVal)) // select ?, X, undef -> X
4124-
return TrueVal;
4125-
41264121
// Deal with partial undef vector constants: select ?, VecC, VecC' --> VecC''
41274122
Constant *TrueC, *FalseC;
41284123
if (TrueVal->getType()->isVectorTy() && match(TrueVal, m_Constant(TrueC)) &&

llvm/test/Transforms/InstCombine/select.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,3 +2273,43 @@ exit:
22732273
%sel = select i1 %cond, i32 %phi, i32 %A
22742274
ret i32 %sel
22752275
}
2276+
2277+
; Negative tests to ensure we don't remove selects with undef true/false values.
2278+
; See https://bugs.llvm.org/show_bug.cgi?id=31633
2279+
; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html
2280+
; https://reviews.llvm.org/D83360
2281+
define i32 @false_undef(i1 %cond, i32 %x) {
2282+
; CHECK-LABEL: @false_undef(
2283+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
2284+
; CHECK-NEXT: ret i32 [[S]]
2285+
;
2286+
%s = select i1 %cond, i32 %x, i32 undef
2287+
ret i32 %s
2288+
}
2289+
2290+
define i32 @true_undef(i1 %cond, i32 %x) {
2291+
; CHECK-LABEL: @true_undef(
2292+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
2293+
; CHECK-NEXT: ret i32 [[S]]
2294+
;
2295+
%s = select i1 %cond, i32 undef, i32 %x
2296+
ret i32 %s
2297+
}
2298+
2299+
define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
2300+
; CHECK-LABEL: @false_undef_vec(
2301+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
2302+
; CHECK-NEXT: ret <2 x i32> [[S]]
2303+
;
2304+
%s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
2305+
ret <2 x i32> %s
2306+
}
2307+
2308+
define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
2309+
; CHECK-LABEL: @true_undef_vec(
2310+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
2311+
; CHECK-NEXT: ret <2 x i32> [[S]]
2312+
;
2313+
%s = select i1 %cond, <2 x i32> undef, <2 x i32> %x
2314+
ret <2 x i32> %s
2315+
}

llvm/test/Transforms/InstSimplify/select.ll

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,3 +750,43 @@ define i1 @y_might_be_poison(float %x, float %y) {
750750
%c3 = select i1 %c1, i1 %c2, i1 false
751751
ret i1 %c3
752752
}
753+
754+
; Negative tests to ensure we don't remove selects with undef true/false values.
755+
; See https://bugs.llvm.org/show_bug.cgi?id=31633
756+
; https://lists.llvm.org/pipermail/llvm-dev/2016-October/106182.html
757+
; https://reviews.llvm.org/D83360
758+
define i32 @false_undef(i1 %cond, i32 %x) {
759+
; CHECK-LABEL: @false_undef(
760+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 [[X:%.*]], i32 undef
761+
; CHECK-NEXT: ret i32 [[S]]
762+
;
763+
%s = select i1 %cond, i32 %x, i32 undef
764+
ret i32 %s
765+
}
766+
767+
define i32 @true_undef(i1 %cond, i32 %x) {
768+
; CHECK-LABEL: @true_undef(
769+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], i32 undef, i32 [[X:%.*]]
770+
; CHECK-NEXT: ret i32 [[S]]
771+
;
772+
%s = select i1 %cond, i32 undef, i32 %x
773+
ret i32 %s
774+
}
775+
776+
define <2 x i32> @false_undef_vec(i1 %cond, <2 x i32> %x) {
777+
; CHECK-LABEL: @false_undef_vec(
778+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> [[X:%.*]], <2 x i32> undef
779+
; CHECK-NEXT: ret <2 x i32> [[S]]
780+
;
781+
%s = select i1 %cond, <2 x i32> %x, <2 x i32> undef
782+
ret <2 x i32> %s
783+
}
784+
785+
define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
786+
; CHECK-LABEL: @true_undef_vec(
787+
; CHECK-NEXT: [[S:%.*]] = select i1 [[COND:%.*]], <2 x i32> undef, <2 x i32> [[X:%.*]]
788+
; CHECK-NEXT: ret <2 x i32> [[S]]
789+
;
790+
%s = select i1 %cond, <2 x i32> undef, <2 x i32> %x
791+
ret <2 x i32> %s
792+
}

0 commit comments

Comments
 (0)