[llvm] [InstCombine] Loosen one-use restriction if common operand is constant (PR #79767)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 2 14:07:48 PST 2024
https://github.com/AtariDreams updated https://github.com/llvm/llvm-project/pull/79767
>From 054c99b9b94b131f9d929d5a4d3c1444bf35c161 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sun, 28 Jan 2024 15:32:44 -0500
Subject: [PATCH 1/3] [InstCombine] pre-commit tests (NFC)
---
llvm/test/Transforms/InstCombine/xor-and-or.ll | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/xor-and-or.ll b/llvm/test/Transforms/InstCombine/xor-and-or.ll
index feba47912b1da..0f82b4ad7e4b0 100644
--- a/llvm/test/Transforms/InstCombine/xor-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll
@@ -241,4 +241,19 @@ define i1 @xor_and_or_negative_oneuse(i1 %c, i1 %x, i1 %y) {
ret i1 %r
}
+define i32 @xor_and_or_constant(i32 %B, i32 %C) {
+; CHECK-LABEL: @xor_and_or_constant(
+; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], 42
+; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C:%.*]], 42
+; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[TMP4]]
+;
+ %1 = or i32 42, %B
+ %2 = or i32 42, %C
+ %3 = xor i32 %1, %2
+ %4 = add i32 %3, %1 ; thwart one-use optimization
+ ret i32 %4
+}
+
declare void @use(i1)
>From 3f991aa61395fbf5ce3af2834a85d839cae87bf5 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Fri, 2 Feb 2024 16:59:34 -0500
Subject: [PATCH 2/3] Update xor-and-or.ll
---
.../test/Transforms/InstCombine/xor-and-or.ll | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/xor-and-or.ll b/llvm/test/Transforms/InstCombine/xor-and-or.ll
index 0f82b4ad7e4b0..604a01c47e1f7 100644
--- a/llvm/test/Transforms/InstCombine/xor-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll
@@ -243,17 +243,19 @@ define i1 @xor_and_or_negative_oneuse(i1 %c, i1 %x, i1 %y) {
define i32 @xor_and_or_constant(i32 %B, i32 %C) {
; CHECK-LABEL: @xor_and_or_constant(
-; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[B:%.*]], 42
-; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[C:%.*]], 42
-; CHECK-NEXT: [[TMP3:%.*]] = xor i32 [[TMP1]], [[TMP2]]
-; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], [[TMP1]]
-; CHECK-NEXT: ret i32 [[TMP4]]
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @use2(i32 42, i32 42)
+; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[C:%.*]], -43
+; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: ret i32 [[TMP3]]
;
- %1 = or i32 42, %B
+ %1 = or i32 42, 42
%2 = or i32 42, %C
- %3 = xor i32 %1, %2
- %4 = add i32 %3, %1 ; thwart one-use optimization
- ret i32 %4
+ %3 = call i32 @use2(i32 42, i32 42) ; thwart one-use optimization
+ %4 = xor i32 %1, %2
+ %5 = add i32 %3, %4
+
+ ret i32 %5
}
declare void @use(i1)
+declare i32 @use2(i32, i32)
>From 551c24155922e8b70b193f0e54e459727141b551 Mon Sep 17 00:00:00 2001
From: Rose <83477269+AtariDreams at users.noreply.github.com>
Date: Sun, 28 Jan 2024 13:30:29 -0500
Subject: [PATCH 3/3] [InstCombine] Loosen one-use restriction if common
operand is constant
Add a new version that checks if A is a constant instead of one-use.
---
.../Transforms/InstCombine/InstCombineAndOrXor.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 1cfa797be2207..5a31cc1359a79 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4798,7 +4798,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
return BinaryOperator::CreateNot(Builder.CreateAnd(Op0, B));
// (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
- // TODO: Loosen one-use restriction if common operand is a constant.
Value *D;
if (match(Op0, m_OneUse(m_Or(m_Value(A), m_Value(B)))) &&
match(Op1, m_OneUse(m_Or(m_Value(C), m_Value(D))))) {
@@ -4812,6 +4811,16 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
}
}
+ // (A | B) ^ (A | C) --> (B ^ C) & ~A -- There are 4 commuted variants.
+ // We do this if common operand is a constant.
+ if (match(Op0, m_c_Or(m_Value(A), m_Value(B))) &&
+ match(Op1, m_c_Or(m_Specific(A), m_Value(C)))) {
+ if (match(A, m_ImmConstant())) {
+ Value *NotA = Builder.CreateNot(A);
+ return BinaryOperator::CreateAnd(Builder.CreateXor(B, C), NotA);
+ }
+ }
+
// (A & B) ^ (A | C) --> A ? ~B : C -- There are 4 commuted variants.
if (I.getType()->isIntOrIntVectorTy(1) &&
match(Op0, m_OneUse(m_LogicalAnd(m_Value(A), m_Value(B)))) &&
More information about the llvm-commits
mailing list