[llvm] [InstCombine] Fixing wrong merge of vector operands with undef elements (PR #102742)

Jorge Botto via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 12:50:08 PDT 2024


https://github.com/jf-botto updated https://github.com/llvm/llvm-project/pull/102742

>From d32f291043504d01c90289967844934891dd9317 Mon Sep 17 00:00:00 2001
From: Jorge Botto <jorge.botto.16 at ucl.ac.uk>
Date: Fri, 9 Aug 2024 00:58:32 +0100
Subject: [PATCH 1/2] Precommit test

---
 llvm/test/Transforms/InstCombine/pr97730.ll | 32 +++++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/pr97730.ll

diff --git a/llvm/test/Transforms/InstCombine/pr97730.ll b/llvm/test/Transforms/InstCombine/pr97730.ll
new file mode 100644
index 00000000000000..3efd26199d74ac
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pr97730.ll
@@ -0,0 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+define <4 x i1> @pr97730-1(<4 x i1> %val0, <4 x i1> %val1, <4 x i1> %val2) {
+; CHECK-LABEL: define <4 x i1> @pr97730-1(
+; CHECK-SAME: <4 x i1> [[VAL0:%.*]], <4 x i1> [[VAL1:%.*]], <4 x i1> [[VAL2:%.*]]) {
+; CHECK-NEXT:    [[VAL4:%.*]] = xor <4 x i1> [[VAL0]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i1> [[VAL4]], [[VAL1]]
+; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[TMP0]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    ret <4 x i1> [[VAL6]]
+;
+  %val3 = add <4 x i1> %val1, <i1 true, i1 true, i1 true, i1 true>
+  %val4 = xor <4 x i1> <i1 false, i1 undef, i1 undef, i1 true>, %val0
+  %val5 = and <4 x i1> %val4, %val3
+  %val6 = sub <4 x i1> %val5, %val0
+  ret <4 x i1> %val6
+}
+
+define <4 x i1> @pr97730-2(<4 x i1> %val0, <4 x i1> %val1, <4 x i1> %val2) {
+; CHECK-LABEL: define <4 x i1> @pr97730-2(
+; CHECK-SAME: <4 x i1> [[VAL0:%.*]], <4 x i1> [[VAL1:%.*]], <4 x i1> [[VAL2:%.*]]) {
+; CHECK-NEXT:    [[VAL4:%.*]] = xor <4 x i1> [[VAL0]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i1> [[VAL4]], [[VAL1]]
+; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[TMP1]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    ret <4 x i1> [[VAL6]]
+;
+  %val3 = xor <4 x i1> %val1, <i1 true, i1 true, i1 true, i1 true>
+  %val4 = xor <4 x i1> <i1 false, i1 undef, i1 undef, i1 true>, %val0
+  %val5 = and <4 x i1> %val4, %val3
+  %val6 = sub <4 x i1> %val5, %val0
+  ret <4 x i1> %val6
+}

>From acfcc00a4ffa31541e665da13a39aea7a42d0720 Mon Sep 17 00:00:00 2001
From: Jorge Botto <jorge.botto.16 at ucl.ac.uk>
Date: Sat, 10 Aug 2024 12:14:32 +0100
Subject: [PATCH 2/2] Fixing miscompilation

---
 .../lib/Transforms/InstCombine/InstCombineAndOrXor.cpp |  5 +++++
 llvm/test/Transforms/InstCombine/pr97730.ll            | 10 ++++++----
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 2bba83b5cde3c7..eb93e4287ab590 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4257,6 +4257,11 @@ static Instruction *visitMaskedMerge(BinaryOperator &I,
 
   Value *NotM;
   if (match(M, m_Not(m_Value(NotM)))) {
+
+    if (ConstantVector *C = dyn_cast<ConstantVector>(X))
+      if (C->containsUndefElement())
+        return nullptr;
+
     // De-invert the mask and swap the value in B part.
     Value *NewA = Builder.CreateAnd(D, NotM);
     return BinaryOperator::CreateXor(NewA, X);
diff --git a/llvm/test/Transforms/InstCombine/pr97730.ll b/llvm/test/Transforms/InstCombine/pr97730.ll
index 3efd26199d74ac..ca2f462517b0e3 100644
--- a/llvm/test/Transforms/InstCombine/pr97730.ll
+++ b/llvm/test/Transforms/InstCombine/pr97730.ll
@@ -4,9 +4,10 @@
 define <4 x i1> @pr97730-1(<4 x i1> %val0, <4 x i1> %val1, <4 x i1> %val2) {
 ; CHECK-LABEL: define <4 x i1> @pr97730-1(
 ; CHECK-SAME: <4 x i1> [[VAL0:%.*]], <4 x i1> [[VAL1:%.*]], <4 x i1> [[VAL2:%.*]]) {
+; CHECK-NEXT:    [[VAL3:%.*]] = xor <4 x i1> [[VAL1]], <i1 true, i1 true, i1 true, i1 true>
 ; CHECK-NEXT:    [[VAL4:%.*]] = xor <4 x i1> [[VAL0]], <i1 false, i1 undef, i1 undef, i1 true>
-; CHECK-NEXT:    [[TMP0:%.*]] = and <4 x i1> [[VAL4]], [[VAL1]]
-; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[TMP0]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    [[VAL5:%.*]] = and <4 x i1> [[VAL4]], [[VAL3]]
+; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[VAL0]], [[VAL5]]
 ; CHECK-NEXT:    ret <4 x i1> [[VAL6]]
 ;
   %val3 = add <4 x i1> %val1, <i1 true, i1 true, i1 true, i1 true>
@@ -19,9 +20,10 @@ define <4 x i1> @pr97730-1(<4 x i1> %val0, <4 x i1> %val1, <4 x i1> %val2) {
 define <4 x i1> @pr97730-2(<4 x i1> %val0, <4 x i1> %val1, <4 x i1> %val2) {
 ; CHECK-LABEL: define <4 x i1> @pr97730-2(
 ; CHECK-SAME: <4 x i1> [[VAL0:%.*]], <4 x i1> [[VAL1:%.*]], <4 x i1> [[VAL2:%.*]]) {
+; CHECK-NEXT:    [[VAL3:%.*]] = xor <4 x i1> [[VAL1]], <i1 true, i1 true, i1 true, i1 true>
 ; CHECK-NEXT:    [[VAL4:%.*]] = xor <4 x i1> [[VAL0]], <i1 false, i1 undef, i1 undef, i1 true>
-; CHECK-NEXT:    [[TMP1:%.*]] = and <4 x i1> [[VAL4]], [[VAL1]]
-; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[TMP1]], <i1 false, i1 undef, i1 undef, i1 true>
+; CHECK-NEXT:    [[VAL5:%.*]] = and <4 x i1> [[VAL4]], [[VAL3]]
+; CHECK-NEXT:    [[VAL6:%.*]] = xor <4 x i1> [[VAL0]], [[VAL5]]
 ; CHECK-NEXT:    ret <4 x i1> [[VAL6]]
 ;
   %val3 = xor <4 x i1> %val1, <i1 true, i1 true, i1 true, i1 true>



More information about the llvm-commits mailing list