The DAG combiner was performing a BT combine. The BT combine had a value of -1,

so it changed it into a 31 via the TLO.ShrinkDemandedConstant() call. Then it
would go through the DAG combiner again. This time it had a value of 31, which
was turned into a -1 by TLI.SimplifyDemandedBits(). This would ping pong
forever.

Teach the TLO.ShrinkDemandedConstant() call not to lower a value if the demanded
value is an XOR of all ones.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@65985 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2009-03-04 00:18:06 +00:00
parent 127a7936de
commit 36ae6c1827
2 changed files with 59 additions and 11 deletions

View File

@ -746,23 +746,34 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op,
const APInt &Demanded) {
DebugLoc dl = Op.getDebugLoc();
// FIXME: ISD::SELECT, ISD::SELECT_CC
switch (Op.getOpcode()) {
default: break;
case ISD::AND:
case ISD::OR:
case ISD::XOR:
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
if (C->getAPIntValue().intersects(~Demanded)) {
MVT VT = Op.getValueType();
SDValue New = DAG.getNode(Op.getOpcode(), dl, VT, Op.getOperand(0),
DAG.getConstant(Demanded &
C->getAPIntValue(),
VT));
return CombineTo(Op, New);
}
case ISD::AND:
case ISD::OR: {
ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
if (!C) return false;
if (Op.getOpcode() == ISD::XOR &&
(C->getAPIntValue() | (~Demanded)).isAllOnesValue())
return false;
// if we can expand it to have all bits set, do it
if (C->getAPIntValue().intersects(~Demanded)) {
MVT VT = Op.getValueType();
SDValue New = DAG.getNode(Op.getOpcode(), dl, VT, Op.getOperand(0),
DAG.getConstant(Demanded &
C->getAPIntValue(),
VT));
return CombineTo(Op, New);
}
break;
}
}
return false;
}

View File

@ -0,0 +1,37 @@
; RUN: llvm-as < %s | llc -march=x86
; rdar://6642541
%struct.HandleBlock = type { [30 x i32], [990 x i8*], %struct.HandleBlockTrailer }
%struct.HandleBlockTrailer = type { %struct.HandleBlock* }
define hidden zeroext i8 @IsHandleAllocatedFromPool(i8** %h) nounwind optsize {
entry:
%0 = ptrtoint i8** %h to i32 ; <i32> [#uses=2]
%1 = and i32 %0, -4096 ; <i32> [#uses=1]
%2 = inttoptr i32 %1 to %struct.HandleBlock* ; <%struct.HandleBlock*> [#uses=3]
%3 = getelementptr %struct.HandleBlock* %2, i32 0, i32 0, i32 0 ; <i32*> [#uses=1]
%4 = load i32* %3, align 4096 ; <i32> [#uses=1]
%5 = icmp eq i32 %4, 1751280747 ; <i1> [#uses=1]
br i1 %5, label %bb, label %bb1
bb: ; preds = %entry
%6 = getelementptr %struct.HandleBlock* %2, i32 0, i32 1 ; <[990 x i8*]*> [#uses=1]
%7 = ptrtoint [990 x i8*]* %6 to i32 ; <i32> [#uses=1]
%8 = sub i32 %0, %7 ; <i32> [#uses=2]
%9 = lshr i32 %8, 2 ; <i32> [#uses=1]
%10 = ashr i32 %8, 7 ; <i32> [#uses=1]
%11 = and i32 %10, 134217727 ; <i32> [#uses=1]
%12 = getelementptr %struct.HandleBlock* %2, i32 0, i32 0, i32 %11 ; <i32*> [#uses=1]
%not.i = and i32 %9, 31 ; <i32> [#uses=1]
%13 = xor i32 %not.i, 31 ; <i32> [#uses=1]
%14 = shl i32 1, %13 ; <i32> [#uses=1]
%15 = load i32* %12, align 4 ; <i32> [#uses=1]
%16 = and i32 %15, %14 ; <i32> [#uses=1]
%17 = icmp eq i32 %16, 0 ; <i1> [#uses=1]
%tmp = zext i1 %17 to i8 ; <i8> [#uses=1]
ret i8 %tmp
bb1: ; preds = %entry
ret i8 0
}