[InstSimplify] allow undef element match in vector select condition value
authorSanjay Patel <spatel@rotateright.com>
Tue, 25 May 2021 18:18:07 +0000 (14:18 -0400)
committerSanjay Patel <spatel@rotateright.com>
Tue, 25 May 2021 18:25:34 +0000 (14:25 -0400)
The semantics of select with undefined/poison condition
are not explicitly stated in the LangRef, but this matches
comments in the code and Alive2 appears to concur:
https://alive2.llvm.org/ce/z/KXytmd

We can find this pattern after demanded elements transforms.

As noted in D101191, fuzzers are finding infinite loops because
we may not account for this pattern in other passes.

llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstCombine/select.ll
llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
llvm/test/Transforms/InstSimplify/select.ll

index 778ce93..c72670b 100644 (file)
@@ -4153,13 +4153,13 @@ static Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
     if (Q.isUndefValue(CondC))
       return isa<Constant>(FalseVal) ? FalseVal : TrueVal;
 
-    // TODO: Vector constants with undef elements don't simplify.
-
-    // select true, X, Y  -> X
-    if (CondC->isAllOnesValue())
+    // select true,  X, Y --> X
+    // select false, X, Y --> Y
+    // For vectors, allow undef/poison elements in the condition to match the
+    // defined elements, so we can eliminate the select.
+    if (match(CondC, m_One()))
       return TrueVal;
-    // select false, X, Y -> Y
-    if (CondC->isNullValue())
+    if (match(CondC, m_Zero()))
       return FalseVal;
   }
 
index a51bb8b..9ff778b 100644 (file)
@@ -2838,8 +2838,7 @@ define <2 x i1> @partial_true_undef_condval(<2 x i1> %x) {
 
 define <2 x i1> @partial_false_undef_condval(<2 x i1> %x) {
 ; CHECK-LABEL: @partial_false_undef_condval(
-; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> <i1 false, i1 poison>, <2 x i1> [[X:%.*]], <2 x i1> <i1 false, i1 poison>
-; CHECK-NEXT:    ret <2 x i1> [[R]]
+; CHECK-NEXT:    ret <2 x i1> <i1 false, i1 poison>
 ;
   %r = select <2 x i1> <i1 false, i1 poison>, <2 x i1> %x, <2 x i1> <i1 false, i1 poison>
   ret <2 x i1> %r
index a949740..bf960d3 100644 (file)
@@ -105,12 +105,9 @@ define <2 x i8> @vsel_mixedvec() {
   ret <2 x i8> %s
 }
 
-; FIXME: Allow for undef elements in a constant vector condition.
-
 define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
 ; CHECK-LABEL: @vsel_undef_true_op(
-; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]
-; CHECK-NEXT:    ret <3 x i8> [[S]]
+; CHECK-NEXT:    ret <3 x i8> [[X:%.*]]
 ;
   %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y
   ret <3 x i8> %s
@@ -118,8 +115,7 @@ define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
 
 define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) {
 ; CHECK-LABEL: @vsel_undef_false_op(
-; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]]
-; CHECK-NEXT:    ret <3 x i4> [[S]]
+; CHECK-NEXT:    ret <3 x i4> [[Y:%.*]]
 ;
   %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y
   ret <3 x i4> %s
index acb998b..3edcb62 100644 (file)
@@ -105,12 +105,9 @@ define <2 x i8> @vsel_mixedvec() {
   ret <2 x i8> %s
 }
 
-; FIXME: Allow for undef elements in a constant vector condition.
-
 define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
 ; CHECK-LABEL: @vsel_undef_true_op(
-; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 true, i1 undef, i1 true>, <3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]
-; CHECK-NEXT:    ret <3 x i8> [[S]]
+; CHECK-NEXT:    ret <3 x i8> [[X:%.*]]
 ;
   %s = select <3 x i1><i1 1, i1 undef, i1 1>, <3 x i8> %x, <3 x i8> %y
   ret <3 x i8> %s
@@ -118,8 +115,7 @@ define <3 x i8> @vsel_undef_true_op(<3 x i8> %x, <3 x i8> %y) {
 
 define <3 x i4> @vsel_undef_false_op(<3 x i4> %x, <3 x i4> %y) {
 ; CHECK-LABEL: @vsel_undef_false_op(
-; CHECK-NEXT:    [[S:%.*]] = select <3 x i1> <i1 false, i1 undef, i1 undef>, <3 x i4> [[X:%.*]], <3 x i4> [[Y:%.*]]
-; CHECK-NEXT:    ret <3 x i4> [[S]]
+; CHECK-NEXT:    ret <3 x i4> [[Y:%.*]]
 ;
   %s = select <3 x i1><i1 0, i1 undef, i1 undef>, <3 x i4> %x, <3 x i4> %y
   ret <3 x i4> %s