[llvm] 0a37290 - [InstSimplify] restrict logic fold with partial undef vector

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 14 09:09:38 PST 2022


Author: Sanjay Patel
Date: 2022-11-14T12:09:23-05:00
New Revision: 0a37290dc81037b966cb7dbfdaad71b46743daad

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

LOG: [InstSimplify] restrict logic fold with partial undef vector

https://alive2.llvm.org/ce/z/4ncsnX

Fixes #58977

Added: 
    

Modified: 
    llvm/lib/Analysis/InstructionSimplify.cpp
    llvm/test/Transforms/InstSimplify/AndOrXor.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index bfb960a02a98a..11ceff1a636d1 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2241,7 +2241,7 @@ static Value *simplifyOrLogic(Value *X, Value *Y) {
   // (B ^ ~A) | (A & B) --> B ^ ~A
   // (~A ^ B) | (B & A) --> ~A ^ B
   // (B ^ ~A) | (B & A) --> B ^ ~A
-  if (match(X, m_c_Xor(m_Not(m_Value(A)), m_Value(B))) &&
+  if (match(X, m_c_Xor(m_NotForbidUndef(m_Value(A)), m_Value(B))) &&
       match(Y, m_c_And(m_Specific(A), m_Specific(B))))
     return X;
 

diff  --git a/llvm/test/Transforms/InstSimplify/AndOrXor.ll b/llvm/test/Transforms/InstSimplify/AndOrXor.ll
index 7f1fcfed0f394..1c700e3c2c307 100644
--- a/llvm/test/Transforms/InstSimplify/AndOrXor.ll
+++ b/llvm/test/Transforms/InstSimplify/AndOrXor.ll
@@ -680,9 +680,26 @@ define i3 @or_xorn_and_commute1(i3 %a, i3 %b) {
 
 define <2 x i32> @or_xorn_and_commute2(<2 x i32> %a, <2 x i32> %b) {
 ; CHECK-LABEL: @or_xorn_and_commute2(
-; CHECK-NEXT:    [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 undef, i32 -1>
+; CHECK-NEXT:    [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 -1, i32 -1>
 ; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[B:%.*]], [[NEGA]]
 ; CHECK-NEXT:    ret <2 x i32> [[XOR]]
+;
+  %nega = xor <2 x i32> %a, <i32 -1, i32 -1>
+  %and = and <2 x i32> %b, %a
+  %xor = xor <2 x i32> %b, %nega
+  %or = or <2 x i32> %xor, %and
+  ret <2 x i32> %or
+}
+
+; This is not safe to fold because the extra logic ops limit the undef-ness of the result.
+
+define <2 x i32> @or_xorn_and_commute2_undef(<2 x i32> %a, <2 x i32> %b) {
+; CHECK-LABEL: @or_xorn_and_commute2_undef(
+; CHECK-NEXT:    [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 undef, i32 -1>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[B:%.*]], [[A]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[B]], [[NEGA]]
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[XOR]], [[AND]]
+; CHECK-NEXT:    ret <2 x i32> [[OR]]
 ;
   %nega = xor <2 x i32> %a, <i32 undef, i32 -1>
   %and = and <2 x i32> %b, %a
@@ -691,6 +708,23 @@ define <2 x i32> @or_xorn_and_commute2(<2 x i32> %a, <2 x i32> %b) {
   ret <2 x i32> %or
 }
 
+; TODO: Unlike the above test, this is safe to fold.
+
+define <2 x i32> @or_xorn_and_commute2_poison(<2 x i32> %a, <2 x i32> %b) {
+; CHECK-LABEL: @or_xorn_and_commute2_poison(
+; CHECK-NEXT:    [[NEGA:%.*]] = xor <2 x i32> [[A:%.*]], <i32 poison, i32 -1>
+; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[B:%.*]], [[A]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i32> [[B]], [[NEGA]]
+; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[XOR]], [[AND]]
+; CHECK-NEXT:    ret <2 x i32> [[OR]]
+;
+  %nega = xor <2 x i32> %a, <i32 poison, i32 -1>
+  %and = and <2 x i32> %b, %a
+  %xor = xor <2 x i32> %b, %nega
+  %or = or <2 x i32> %xor, %and
+  ret <2 x i32> %or
+}
+
 define i32 @or_xorn_and_commute3(i32 %a, i32 %b) {
 ; CHECK-LABEL: @or_xorn_and_commute3(
 ; CHECK-NEXT:    [[NEGA:%.*]] = xor i32 [[A:%.*]], -1


        


More information about the llvm-commits mailing list