In InstCombiner::visitOr, make sure we reverse the operand swap used for checking for or-of-xor operations after those checks; a later check expects that any constant will be in Op1. PR12234.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152884 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2012-03-16 00:52:42 +00:00
parent 213d2e7dc3
commit e9f15c8a56
2 changed files with 19 additions and 1 deletions

View File

@ -1929,8 +1929,11 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
}
// Canonicalize xor to the RHS.
if (match(Op0, m_Xor(m_Value(), m_Value())))
bool SwappedForXor = false;
if (match(Op0, m_Xor(m_Value(), m_Value()))) {
std::swap(Op0, Op1);
SwappedForXor = true;
}
// A | ( A ^ B) -> A | B
// A | (~A ^ B) -> A | ~B
@ -1961,6 +1964,9 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
return BinaryOperator::CreateOr(Not, Op0);
}
if (SwappedForXor)
std::swap(Op0, Op1);
if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
if (ICmpInst *LHS = dyn_cast<ICmpInst>(I.getOperand(0)))
if (Value *Res = FoldOrOfICmps(LHS, RHS))

View File

@ -0,0 +1,12 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
; PR12234
@g = extern_weak global i32
define i32 @function(i32 %x) nounwind {
entry:
%xor = xor i32 %x, 1
store volatile i32 %xor, i32* inttoptr (i64 1 to i32*), align 4
%or4 = or i32 or (i32 zext (i1 icmp eq (i32* @g, i32* null) to i32), i32 1), %xor
ret i32 %or4
}
; CHECK: define i32 @function