mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-04 10:04:33 +00:00
revert r301923 : [InstCombine] don't use DeMorgan's Law on integer constants
There's a clang test that is wrongly using -O1 and failing after this commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301924 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9697c664a6
commit
a30d9c6883
@ -2433,32 +2433,29 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
|
||||
if (Value *V = SimplifyBSwap(I))
|
||||
return replaceInstUsesWith(I, V);
|
||||
|
||||
// Apply DeMorgan's Law for 'nand' / 'nor' logic with an inverted operand.
|
||||
Value *X, *Y;
|
||||
|
||||
// We must eliminate the and/or (one-use) for these transforms to not increase
|
||||
// the instruction count.
|
||||
// ~(~X & Y) --> (X | ~Y)
|
||||
// ~(Y & ~X) --> (X | ~Y)
|
||||
if (match(&I, m_Not(m_OneUse(m_c_And(m_Not(m_Value(X)), m_Value(Y)))))) {
|
||||
Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not");
|
||||
return BinaryOperator::CreateOr(X, NotY);
|
||||
}
|
||||
// ~(~X | Y) --> (X & ~Y)
|
||||
// ~(Y | ~X) --> (X & ~Y)
|
||||
if (match(&I, m_Not(m_OneUse(m_c_Or(m_Not(m_Value(X)), m_Value(Y)))))) {
|
||||
Value *NotY = Builder->CreateNot(Y, Y->getName() + ".not");
|
||||
return BinaryOperator::CreateAnd(X, NotY);
|
||||
}
|
||||
|
||||
// Is this a 'not' (~) fed by a binary operator?
|
||||
BinaryOperator *NotOp;
|
||||
if (match(&I, m_Not(m_BinOp(NotOp)))) {
|
||||
if (NotOp->getOpcode() == Instruction::And ||
|
||||
NotOp->getOpcode() == Instruction::Or) {
|
||||
// Apply DeMorgan's Law when inverts are free:
|
||||
// ~(X & Y) --> (~X | ~Y)
|
||||
// ~(X | Y) --> (~X & ~Y)
|
||||
// We must eliminate the and/or for this transform to not increase the
|
||||
// instruction count.
|
||||
if (NotOp->hasOneUse()) {
|
||||
// ~(~X & Y) --> (X | ~Y) - De Morgan's Law
|
||||
// ~(~X | Y) === (X & ~Y) - De Morgan's Law
|
||||
if (dyn_castNotVal(NotOp->getOperand(1)))
|
||||
NotOp->swapOperands();
|
||||
if (Value *Op0NotVal = dyn_castNotVal(NotOp->getOperand(0))) {
|
||||
Value *NotY = Builder->CreateNot(
|
||||
NotOp->getOperand(1), NotOp->getOperand(1)->getName() + ".not");
|
||||
if (NotOp->getOpcode() == Instruction::And)
|
||||
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(NotOp->getOperand(0),
|
||||
NotOp->getOperand(0)->hasOneUse()) &&
|
||||
IsFreeToInvert(NotOp->getOperand(1),
|
||||
|
@ -21,8 +21,8 @@ define i32 @test1(i32 %a) #0 {
|
||||
|
||||
define i32 @test2(i32 %a) #0 {
|
||||
; CHECK-LABEL: @test2(
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 15
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 10
|
||||
; CHECK-NEXT: [[A_NOT:%.*]] = or i32 [[A:%.*]], -16
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A_NOT]], -6
|
||||
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
|
||||
; CHECK-NEXT: ret i32 2
|
||||
;
|
||||
@ -50,8 +50,8 @@ define i32 @test3(i32 %a) #0 {
|
||||
|
||||
define i32 @test4(i32 %a) #0 {
|
||||
; CHECK-LABEL: @test4(
|
||||
; CHECK-NEXT: [[V:%.*]] = or i32 [[A:%.*]], -16
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V]], -6
|
||||
; CHECK-NEXT: [[A_NOT:%.*]] = and i32 [[A:%.*]], 15
|
||||
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A_NOT]], 10
|
||||
; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP]])
|
||||
; CHECK-NEXT: ret i32 2
|
||||
;
|
||||
|
@ -367,12 +367,12 @@ define i8 @demorgan_nor_use2bc(i8 %A, i8 %B) {
|
||||
ret i8 %r2
|
||||
}
|
||||
|
||||
; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
|
||||
; FIXME: Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
|
||||
|
||||
define i32 @demorganize_constant1(i32 %a) {
|
||||
; CHECK-LABEL: @demorganize_constant1(
|
||||
; CHECK-NEXT: [[AND:%.*]] = and i32 %a, 15
|
||||
; CHECK-NEXT: [[AND1:%.*]] = xor i32 [[AND]], -1
|
||||
; CHECK-NEXT: [[A_NOT:%.*]] = or i32 %a, -16
|
||||
; CHECK-NEXT: [[AND1:%.*]] = xor i32 [[A_NOT]], 15
|
||||
; CHECK-NEXT: ret i32 [[AND1]]
|
||||
;
|
||||
%and = and i32 %a, 15
|
||||
@ -380,12 +380,12 @@ define i32 @demorganize_constant1(i32 %a) {
|
||||
ret i32 %and1
|
||||
}
|
||||
|
||||
; Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
|
||||
; FIXME: Do not apply DeMorgan's Law to constants. We prefer 'not' ops.
|
||||
|
||||
define i32 @demorganize_constant2(i32 %a) {
|
||||
; CHECK-LABEL: @demorganize_constant2(
|
||||
; CHECK-NEXT: [[AND:%.*]] = or i32 %a, 15
|
||||
; CHECK-NEXT: [[AND1:%.*]] = xor i32 [[AND]], -1
|
||||
; CHECK-NEXT: [[A_NOT:%.*]] = and i32 %a, -16
|
||||
; CHECK-NEXT: [[AND1:%.*]] = xor i32 [[A_NOT]], -16
|
||||
; CHECK-NEXT: ret i32 [[AND1]]
|
||||
;
|
||||
%and = or i32 %a, 15
|
||||
|
Loading…
Reference in New Issue
Block a user