diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-05-10 21:33:55 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-05-10 21:33:55 +0000 |
commit | 40a87a909b5c75099ff57ccf5da065f2cf6eea72 (patch) | |
tree | 5628ce691fd4c89c94d46a1439dcc89dcbac861d | |
parent | 52f8d19ceda6a166497e71c5faaa6a4c07f0bbef (diff) | |
download | bcm5719-llvm-40a87a909b5c75099ff57ccf5da065f2cf6eea72.tar.gz bcm5719-llvm-40a87a909b5c75099ff57ccf5da065f2cf6eea72.zip |
[InstCombine] remove fold that swaps xor/or with constants; NFCI
// (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
This canonicalization was added at:
https://reviews.llvm.org/rL7264
By moving xors out/down, we can more easily combine constants. I'm adding
tests that do not change with this patch, so we can verify that those kinds
of transforms are still happening.
This is no-functional-change-intended because there's a later fold:
// (X^C)|Y -> (X|Y)^C iff Y&C == 0
...and demanded-bits appears to guarantee that any fold that would have
hit the fold we're removing here would be caught by that 2nd fold.
Similar reasoning was used in:
https://reviews.llvm.org/rL299384
The larger motivation for removing this code is that it could interfere with
the fix for PR32706:
https://bugs.llvm.org/show_bug.cgi?id=32706
Ie, we're not checking if the 'xor' is actually a 'not', so we could reverse
a 'not' optimization and cause an infinite loop by altering an 'xor X, -1'.
Differential Revision: https://reviews.llvm.org/D33050
llvm-svn: 302733
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 12 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/or-xor.ll | 70 |
2 files changed, 70 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index f7d9558ad27..629f9be8a0a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1986,18 +1986,6 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { if (Value *V = SimplifyBSwap(I)) return replaceInstUsesWith(I, V); - if (ConstantInt *RHS = dyn_cast<ConstantInt>(Op1)) { - ConstantInt *C1 = nullptr; Value *X = nullptr; - // (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2) - if (match(Op0, m_Xor(m_Value(X), m_ConstantInt(C1))) && - Op0->hasOneUse()) { - Value *Or = Builder->CreateOr(X, RHS); - Or->takeName(Op0); - return BinaryOperator::CreateXor(Or, - Builder->getInt(C1->getValue() & ~RHS->getValue())); - } - } - if (isa<Constant>(Op1)) if (Instruction *FoldedLogic = foldOpWithConstantIntoOperand(I)) return FoldedLogic; diff --git a/llvm/test/Transforms/InstCombine/or-xor.ll b/llvm/test/Transforms/InstCombine/or-xor.ll index ec5b71656a4..f2bc290d79a 100644 --- a/llvm/test/Transforms/InstCombine/or-xor.ll +++ b/llvm/test/Transforms/InstCombine/or-xor.ll @@ -230,3 +230,73 @@ define i32 @test16(i32 %a, i32 %b) { %xor = or i32 %and1, %and2 ret i32 %xor } + +define i8 @not_or(i8 %x) { +; CHECK-LABEL: @not_or( +; CHECK-NEXT: [[NOTX:%.*]] = or i8 %x, 7 +; CHECK-NEXT: [[OR:%.*]] = xor i8 [[NOTX]], -8 +; CHECK-NEXT: ret i8 [[OR]] +; + %notx = xor i8 %x, -1 + %or = or i8 %notx, 7 + ret i8 %or +} + +define i8 @not_or_xor(i8 %x) { +; CHECK-LABEL: @not_or_xor( +; CHECK-NEXT: [[NOTX:%.*]] = or i8 %x, 7 +; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[NOTX]], -12 +; CHECK-NEXT: ret i8 [[XOR]] +; + %notx = xor i8 %x, -1 + %or = or i8 %notx, 7 + %xor = xor i8 %or, 12 + ret i8 %xor +} + +define i8 @xor_or(i8 %x) { +; CHECK-LABEL: @xor_or( +; CHECK-NEXT: [[XOR:%.*]] = or i8 %x, 7 +; CHECK-NEXT: [[OR:%.*]] = xor i8 [[XOR]], 32 +; CHECK-NEXT: ret i8 [[OR]] +; + %xor = xor i8 %x, 32 + %or = or i8 %xor, 7 + ret i8 %or +} + +define i8 @xor_or2(i8 %x) { +; CHECK-LABEL: @xor_or2( +; CHECK-NEXT: [[XOR:%.*]] = or i8 %x, 7 +; CHECK-NEXT: [[OR:%.*]] = xor i8 [[XOR]], 32 +; CHECK-NEXT: ret i8 [[OR]] +; + %xor = xor i8 %x, 33 + %or = or i8 %xor, 7 + ret i8 %or +} + +define i8 @xor_or_xor(i8 %x) { +; CHECK-LABEL: @xor_or_xor( +; CHECK-NEXT: [[XOR1:%.*]] = or i8 %x, 7 +; CHECK-NEXT: [[XOR2:%.*]] = xor i8 [[XOR1]], 44 +; CHECK-NEXT: ret i8 [[XOR2]] +; + %xor1 = xor i8 %x, 33 + %or = or i8 %xor1, 7 + %xor2 = xor i8 %or, 12 + ret i8 %xor2 +} + +define i8 @or_xor_or(i8 %x) { +; CHECK-LABEL: @or_xor_or( +; CHECK-NEXT: [[XOR:%.*]] = or i8 %x, 39 +; CHECK-NEXT: [[OR2:%.*]] = xor i8 [[XOR]], 8 +; CHECK-NEXT: ret i8 [[OR2]] +; + %or1 = or i8 %x, 33 + %xor = xor i8 %or1, 12 + %or2 = or i8 %xor, 7 + ret i8 %or2 +} + |