mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-24 12:36:30 +00:00
reapply r85085 with a bugfix to avoid infinite looping.
All of the 'demorgan' related xforms need to use dyn_castNotVal, not m_Not. llvm-svn: 85119
This commit is contained in:
parent
3d0c010ee4
commit
7f9ddaf7e3
@ -631,9 +631,32 @@ static inline Value *dyn_castFNegVal(Value *V) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline Value *dyn_castNotVal(Value *V) {
|
||||
/// isFreeToInvert - Return true if the specified value is free to invert (apply
|
||||
/// ~ to). This happens in cases where the ~ can be eliminated.
|
||||
static inline bool isFreeToInvert(Value *V) {
|
||||
// ~(~(X)) -> X.
|
||||
if (BinaryOperator::isNot(V))
|
||||
return BinaryOperator::getNotArgument(V);
|
||||
return true;
|
||||
|
||||
// Constants can be considered to be not'ed values.
|
||||
if (isa<ConstantInt>(V))
|
||||
return true;
|
||||
|
||||
// Compares can be inverted if they have a single use.
|
||||
if (CmpInst *CI = dyn_cast<CmpInst>(V))
|
||||
return CI->hasOneUse();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline Value *dyn_castNotVal(Value *V) {
|
||||
// If this is not(not(x)) don't return that this is a not: we want the two
|
||||
// not's to be folded first.
|
||||
if (BinaryOperator::isNot(V)) {
|
||||
Value *Operand = BinaryOperator::getNotArgument(V);
|
||||
if (!isFreeToInvert(Operand))
|
||||
return Operand;
|
||||
}
|
||||
|
||||
// Constants can be considered to be not'ed values...
|
||||
if (ConstantInt *C = dyn_cast<ConstantInt>(V))
|
||||
@ -641,6 +664,8 @@ static inline Value *dyn_castNotVal(Value *V) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// dyn_castFoldableMul - If this value is a multiply that can be folded into
|
||||
// other computations (because it has a constant operand), return the
|
||||
// non-constant operand of the multiply, and set CST to point to the multiplier.
|
||||
@ -4166,7 +4191,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
|
||||
if (Instruction *CastOp = dyn_cast<Instruction>(CI->getOperand(0))) {
|
||||
if ((isa<TruncInst>(CI) || isa<BitCastInst>(CI)) &&
|
||||
CastOp->getNumOperands() == 2)
|
||||
if (ConstantInt *AndCI = dyn_cast<ConstantInt>(CastOp->getOperand(1))) {
|
||||
if (ConstantInt *AndCI =dyn_cast<ConstantInt>(CastOp->getOperand(1))){
|
||||
if (CastOp->getOpcode() == Instruction::And) {
|
||||
// Change: and (cast (and X, C1) to T), C2
|
||||
// into : and (cast X to T), trunc_or_bitcast(C1)&C2
|
||||
@ -4960,14 +4985,14 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
|
||||
if (Ret) return Ret;
|
||||
}
|
||||
|
||||
if (match(Op0, m_Not(m_Value(A)))) { // ~A | Op1
|
||||
if ((A = dyn_castNotVal(Op0))) { // ~A | Op1
|
||||
if (A == Op1) // ~A | A == -1
|
||||
return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));
|
||||
} else {
|
||||
A = 0;
|
||||
}
|
||||
// Note, A is still live here!
|
||||
if (match(Op1, m_Not(m_Value(B)))) { // Op0 | ~B
|
||||
if ((B = dyn_castNotVal(Op1))) { // Op0 | ~B
|
||||
if (Op0 == B)
|
||||
return ReplaceInstUsesWith(I, Constant::getAllOnesValue(I.getType()));
|
||||
|
||||
@ -5064,12 +5089,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
|
||||
// Is this a ~ operation?
|
||||
if (Value *NotOp = dyn_castNotVal(&I)) {
|
||||
// ~(~X & Y) --> (X | ~Y) - De Morgan's Law
|
||||
// ~(~X | Y) === (X & ~Y) - De Morgan's Law
|
||||
if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(NotOp)) {
|
||||
if (Op0I->getOpcode() == Instruction::And ||
|
||||
Op0I->getOpcode() == Instruction::Or) {
|
||||
if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands();
|
||||
// ~(~X & Y) --> (X | ~Y) - De Morgan's Law
|
||||
// ~(~X | Y) === (X & ~Y) - De Morgan's Law
|
||||
if (dyn_castNotVal(Op0I->getOperand(1)))
|
||||
Op0I->swapOperands();
|
||||
if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) {
|
||||
Value *NotY =
|
||||
Builder->CreateNot(Op0I->getOperand(1),
|
||||
@ -5078,6 +5104,19 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
return BinaryOperator::CreateOr(Op0NotVal, NotY);
|
||||
return BinaryOperator::CreateAnd(Op0NotVal, NotY);
|
||||
}
|
||||
|
||||
// ~(X & Y) --> (~X | ~Y) - De Morgan's Law
|
||||
// ~(X | Y) === (~X & ~Y) - De Morgan's Law
|
||||
if (isFreeToInvert(Op0I->getOperand(0)) &&
|
||||
isFreeToInvert(Op0I->getOperand(1))) {
|
||||
Value *NotX =
|
||||
Builder->CreateNot(Op0I->getOperand(0), "notlhs");
|
||||
Value *NotY =
|
||||
Builder->CreateNot(Op0I->getOperand(1), "notrhs");
|
||||
if (Op0I->getOpcode() == Instruction::And)
|
||||
return BinaryOperator::CreateOr(NotX, NotY);
|
||||
return BinaryOperator::CreateAnd(NotX, NotY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
; This test makes sure that these instructions are properly eliminated.
|
||||
;
|
||||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
; XFAIL: *
|
||||
|
||||
define i32 @test1(i32 %A) {
|
||||
%B = or i32 %A, 0
|
||||
|
Loading…
Reference in New Issue
Block a user