mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-30 17:33:24 +00:00
Implement PR3266 & PR5276, folding:
not (or (icmp, icmp)) -> and(icmp, icmp) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85085 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1125f58efc
commit
863928fc39
@ -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
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,4 +237,19 @@ define i1 @test24(double %X, double %Y) {
|
||||
; CHECK: @test24
|
||||
; CHECK: %bothcond = fcmp uno double %Y, %X ; <i1> [#uses=1]
|
||||
; CHECK: ret i1 %bothcond
|
||||
}
|
||||
}
|
||||
|
||||
; PR3266 & PR5276
|
||||
define i1 @test25(i32 %A, i32 %B) {
|
||||
%C = icmp eq i32 %A, 0
|
||||
%D = icmp eq i32 %B, 57
|
||||
%E = or i1 %C, %D
|
||||
%F = xor i1 %E, -1
|
||||
ret i1 %F
|
||||
|
||||
; CHECK: @test25
|
||||
; CHECK: icmp ne i32 %A, 0
|
||||
; CHECK-NEXT: icmp ne i32 %B, 57
|
||||
; CHECK-NEXT: %F = and i1
|
||||
; CHECK-NEXT: ret i1 %F
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
; RUN: opt < %s -instcombine -S | not grep {= or}
|
||||
; PR3266
|
||||
; XFAIL: *
|
||||
|
||||
define i1 @foo(i32 %x, i32 %y) nounwind {
|
||||
.summary:
|
||||
%0 = icmp sgt i32 %x, 4 ; <i1> [#uses=1]
|
||||
%1 = icmp sgt i32 %y, 0 ; <i1> [#uses=1]
|
||||
%.demorgan = or i1 %1, %0 ; <i1> [#uses=1]
|
||||
%2 = xor i1 %.demorgan, true ; <i1> [#uses=1]
|
||||
ret i1 %2
|
||||
}
|
Loading…
Reference in New Issue
Block a user