forked from OSchip/llvm-project
Back out r160101 and instead implement a dag combine to recover from instcombine transformation.
llvm-svn: 160387
This commit is contained in:
parent
831c1e0819
commit
e6a3b03ee0
|
@ -2716,6 +2716,34 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
|
|||
}
|
||||
}
|
||||
|
||||
if (N0.getOpcode() == ISD::ADD && N1.getOpcode() == ISD::SRL &&
|
||||
VT.getSizeInBits() <= 64) {
|
||||
if (ConstantSDNode *ADDI = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
|
||||
APInt ADDC = ADDI->getAPIntValue();
|
||||
if (!TLI.isLegalAddImmediate(ADDC.getSExtValue())) {
|
||||
// Look for (and (add x, c1), (lshr y, c2)). If C1 wasn't a legal
|
||||
// immediate for an add, but it is legal if its top c2 bits are set,
|
||||
// transform the ADD so the immediate doesn't need to be materialized
|
||||
// in a register.
|
||||
if (ConstantSDNode *SRLI = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
|
||||
APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(),
|
||||
SRLI->getZExtValue());
|
||||
if (DAG.MaskedValueIsZero(N0.getOperand(1), Mask)) {
|
||||
ADDC |= Mask;
|
||||
if (TLI.isLegalAddImmediate(ADDC.getSExtValue())) {
|
||||
SDValue NewAdd =
|
||||
DAG.getNode(ISD::ADD, N0.getDebugLoc(), VT,
|
||||
N0.getOperand(0), DAG.getConstant(ADDC, VT));
|
||||
CombineTo(N0.getNode(), NewAdd);
|
||||
return SDValue(N, 0); // Return N so it doesn't get rechecked!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
|
|
|
@ -11345,6 +11345,7 @@ bool X86TargetLowering::isLegalICmpImmediate(int64_t Imm) const {
|
|||
}
|
||||
|
||||
bool X86TargetLowering::isLegalAddImmediate(int64_t Imm) const {
|
||||
// Can also use sub to handle negated immediates.
|
||||
return Imm == (int32_t)Imm;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,13 +40,6 @@ static bool ShrinkDemandedConstant(Instruction *I, unsigned OpNo,
|
|||
|
||||
// This instruction is producing bits that are not demanded. Shrink the RHS.
|
||||
Demanded &= OpC->getValue();
|
||||
if (I->getOpcode() == Instruction::Add) {
|
||||
// However, if the instruction is an add then the constant may be negated
|
||||
// when the opcode is changed to sub. Check if the transformation is really
|
||||
// shrinking the constant.
|
||||
if (Demanded.abs().getActiveBits() > OpC->getValue().abs().getActiveBits())
|
||||
return false;
|
||||
}
|
||||
I->setOperand(OpNo, ConstantInt::get(OpC->getType(), Demanded));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
; RUN: opt < %s -instcombine -S | FileCheck %s
|
||||
|
||||
; When shrinking demanded constant operand of an add instruction, keep in
|
||||
; mind the opcode can be changed to sub and the constant negated. Make sure
|
||||
; the shrinking the constant would actually reduce the width.
|
||||
; rdar://11793464
|
||||
|
||||
define i64 @t(i64 %key, i64* %val) nounwind {
|
||||
entry:
|
||||
; CHECK: @t
|
||||
; CHECK-NOT: add i64 %0, 2305843009213693951
|
||||
; CHECK: add i64 %0, -1
|
||||
%shr = lshr i64 %key, 3
|
||||
%0 = load i64* %val, align 8
|
||||
%sub = sub i64 %0, 1
|
||||
%and = and i64 %sub, %shr
|
||||
ret i64 %and
|
||||
}
|
Loading…
Reference in New Issue