[llvm] fde8eb0 - [InstCombine] visitMaskedMerge(): when unfolding, sanitize undef constants (PR45955)

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Sun May 17 12:54:42 PDT 2020


Author: Roman Lebedev
Date: 2020-05-17T22:53:03+03:00
New Revision: fde8eb00e1466cecd0fc6697f8c2ab837c5b7cf3

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

LOG: [InstCombine] visitMaskedMerge(): when unfolding, sanitize undef constants (PR45955)

We can't leave undef vector element constants as-is,
it is a miscompile, so we need to sanitize them.

We have two vectors (C and ~C):
* We can't replace undef with 0 in both of them
* We can't replace undef with 0 in only one of them
* We could replace undef with -1 in both of them
* We could replace undef with -1 in only one(!) of them
* We could replace undef with -1 in one and 0 in another one of them.

Therefore, it seems best to go with the last option, since otherwise
we'd loose knowledge that C and ~C have no common bits set,
which seems more important than preserving partial undef knowledge.

Fixes https://bugs.llvm.org/show_bug.cgi?id=45955

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 9bbedb292fbb..35dcb739364b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3049,6 +3049,9 @@ static Instruction *visitMaskedMerge(BinaryOperator &I,
 
   Constant *C;
   if (D->hasOneUse() && match(M, m_Constant(C))) {
+    // Propagating undef is unsafe. Clamp undef elements to -1.
+    Type *EltTy = C->getType()->getScalarType();
+    C = Constant::replaceUndefsWith(C, ConstantInt::getAllOnesValue(EltTy));
     // Unfold.
     Value *LHS = Builder.CreateAnd(X, C);
     Value *NotC = Builder.CreateNot(C);

diff  --git a/llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll b/llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll
index f87b52b97431..4f92514afc87 100644
--- a/llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll
+++ b/llvm/test/Transforms/InstCombine/unfold-masked-merge-with-const-mask-vector.ll
@@ -21,8 +21,8 @@ define <2 x i4> @splat (<2 x i4> %x, <2 x i4> %y) {
 
 define <3 x i4> @splat_undef (<3 x i4> %x, <3 x i4> %y) {
 ; CHECK-LABEL: @splat_undef(
-; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 -2, i4 undef, i4 -2>
-; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i4> [[Y:%.*]], <i4 1, i4 undef, i4 1>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 -2, i4 -1, i4 -2>
+; CHECK-NEXT:    [[TMP2:%.*]] = and <3 x i4> [[Y:%.*]], <i4 1, i4 0, i4 1>
 ; CHECK-NEXT:    [[R:%.*]] = or <3 x i4> [[TMP1]], [[TMP2]]
 ; CHECK-NEXT:    ret <3 x i4> [[R]]
 ;
@@ -85,8 +85,8 @@ define <2 x i4> @in_constant_varx_14_nonsplat(<2 x i4> %x, <2 x i4> %mask) {
 
 define <3 x i4> @in_constant_varx_14_undef(<3 x i4> %x, <3 x i4> %mask) {
 ; CHECK-LABEL: @in_constant_varx_14_undef(
-; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 1, i4 undef, i4 1>
-; CHECK-NEXT:    [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 -2, i4 undef, i4 6>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[X:%.*]], <i4 1, i4 -1, i4 1>
+; CHECK-NEXT:    [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 -2, i4 0, i4 6>
 ; CHECK-NEXT:    ret <3 x i4> [[R]]
 ;
   %n0 = xor <3 x i4> %x, <i4 14, i4 undef, i4 7> ; %x
@@ -133,7 +133,7 @@ define <2 x i4> @in_constant_14_vary_nonsplat(<2 x i4> %y, <2 x i4> %mask) {
 
 define <3 x i4> @in_constant_14_vary_undef(<3 x i4> %y, <3 x i4> %mask) {
 ; CHECK-LABEL: @in_constant_14_vary_undef(
-; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[Y:%.*]], <i4 -2, i4 undef, i4 -2>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <3 x i4> [[Y:%.*]], <i4 -2, i4 0, i4 -2>
 ; CHECK-NEXT:    [[R:%.*]] = or <3 x i4> [[TMP1]], <i4 0, i4 undef, i4 1>
 ; CHECK-NEXT:    ret <3 x i4> [[R]]
 ;


        


More information about the llvm-commits mailing list