[PATCH] D109194: [InstCombine] Optimize (a & b) | (~a & c)
Matthias Braun via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 2 14:03:55 PDT 2021
MatzeB created this revision.
MatzeB added reviewers: lebedev.ri, RKSimon, nikic, spatel, reames.
Herald added subscribers: wenlei, hiraditya, mcrosier.
MatzeB requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
(a & b) | (~a & c) can be optimized into (((b ^ c) & a) ^ c)
I found this while comparing md5 implementations...
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D109194
Files:
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/or.ll
Index: llvm/test/Transforms/InstCombine/or.ll
===================================================================
--- llvm/test/Transforms/InstCombine/or.ll
+++ llvm/test/Transforms/InstCombine/or.ll
@@ -1385,3 +1385,33 @@
%or1 = or i32 %xor, %neg
ret i32 %or1
}
+
+define i32 @test_or_and_and_not(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @test_or_and_and_not(
+; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[C:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[A:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP3]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %and0 = and i32 %a, %b
+ %not_a = xor i32 %a, -1
+ %and1 = and i32 %not_a, %c
+ %or = or i32 %and0, %and1
+ ret i32 %or
+}
+
+define i32 @test_or_and_and_not2(i32 %a, i32 %b, i32 %c) {
+; CHECK-LABEL: @test_or_and_and_not2(
+; CHECK-NEXT: [[TMP1:%.*]] = freeze i32 [[A:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], [[C:%.*]]
+; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], [[B:%.*]]
+; CHECK-NEXT: [[OR:%.*]] = xor i32 [[TMP3]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[OR]]
+;
+ %not_b = xor i32 %b, -1
+ %and0 = and i32 %a, %not_b
+ %and1 = and i32 %b, %c
+ %or = or i32 %and0, %and1
+ ret i32 %or
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2772,6 +2772,21 @@
if (Value *V = matchSelectFromAndOr(D, B, C, A))
return replaceInstUsesWith(I, V);
}
+
+ // (a & b) | (~a & c) -> ((b ^ c_) & a) ^ c_ with c_ = freeze(c)
+ {
+ Value *A, *B, *C;
+ if (Op0->hasOneUse() && Op1->hasOneUse() &&
+ (match(&I, m_BinOp(m_c_And(m_Value(A), m_Value(B)),
+ m_c_And(m_Not(m_Deferred(A)), m_Value(C)))) ||
+ match(&I, m_BinOp(m_c_And(m_Not(m_Value(A)), m_Value(C)),
+ m_c_And(m_Deferred(A), m_Value(B)))))) {
+ Value *FrozenC = Builder.CreateFreeze(C);
+ Value *Xor0 = Builder.CreateXor(B, FrozenC);
+ Value *And = Builder.CreateAnd(Xor0, A);
+ return BinaryOperator::CreateXor(And, FrozenC);
+ }
+ }
}
// (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109194.370398.patch
Type: text/x-patch
Size: 2370 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210902/7e908fa6/attachment-0001.bin>
More information about the llvm-commits
mailing list