[llvm] ca7eaa0 - [InstSimplify] allow undef element match in vector select condition value

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue May 25 11:27:20 PDT 2021


Author: Sanjay Patel
Date: 2021-05-25T14:25:34-04:00
New Revision: ca7eaa0a54938bfe9aeed7ebc64202f0b6f2ce0d

URL: https://github.com/llvm/llvm-project/commit/ca7eaa0a54938bfe9aeed7ebc64202f0b6f2ce0d
DIFF: https://github.com/llvm/llvm-project/commit/ca7eaa0a54938bfe9aeed7ebc64202f0b6f2ce0d.diff

LOG: [InstSimplify] allow undef element match in vector select condition value

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.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 778ce93f61f8..c72670b901fe 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -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;
   }
 

diff  --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index a51bb8bbfedc..9ff778bd0e28 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -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

diff  --git a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
index a949740e8429..bf960d3980ab 100644
--- a/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
+++ b/llvm/test/Transforms/InstSimplify/select-inseltpoison.ll
@@ -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

diff  --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll
index acb998b8518a..3edcb62216f1 100644
--- a/llvm/test/Transforms/InstSimplify/select.ll
+++ b/llvm/test/Transforms/InstSimplify/select.ll
@@ -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


        


More information about the llvm-commits mailing list