[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