diff options
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 11 | ||||
-rw-r--r-- | test/CodeGen/Generic/2014-02-05-OpaqueConstants.ll | 19 |
2 files changed, 28 insertions, 2 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 32c07ad4f5..9b84e4dde3 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3732,6 +3732,12 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { /// visitShiftByConstant - Handle transforms common to the three shifts, when /// the shift amount is a constant. SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { + assert(isa<ConstantSDNode>(N->getOperand(1)) && + "Expected an ConstantSDNode operand."); + // We can't and shouldn't fold opaque constants. + if (cast<ConstantSDNode>(N->getOperand(1))->isOpaque()) + return SDValue(); + SDNode *LHS = N->getOperand(0).getNode(); if (!LHS->hasOneUse()) return SDValue(); @@ -3757,9 +3763,9 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { break; } - // We require the RHS of the binop to be a constant as well. + // We require the RHS of the binop to be a constant and not opaque as well. ConstantSDNode *BinOpCst = dyn_cast<ConstantSDNode>(LHS->getOperand(1)); - if (!BinOpCst) return SDValue(); + if (!BinOpCst || BinOpCst->isOpaque()) return SDValue(); // FIXME: disable this unless the input to the binop is a shift by a constant. // If it is not a shift, it pessimizes some common cases like: @@ -3789,6 +3795,7 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { SDValue NewRHS = DAG.getNode(N->getOpcode(), SDLoc(LHS->getOperand(1)), N->getValueType(0), LHS->getOperand(1), N->getOperand(1)); + assert(isa<ConstantSDNode>(NewRHS) && "Folding was not successful!"); // Create the new shift. SDValue NewShift = DAG.getNode(N->getOpcode(), diff --git a/test/CodeGen/Generic/2014-02-05-OpaqueConstants.ll b/test/CodeGen/Generic/2014-02-05-OpaqueConstants.ll new file mode 100644 index 0000000000..5c1cd05325 --- /dev/null +++ b/test/CodeGen/Generic/2014-02-05-OpaqueConstants.ll @@ -0,0 +1,19 @@ +; Test that opaque constants are not creating an infinite DAGCombine loop +; RUN: llc < %s +; XFAIL: r600, xcore + +@a = common global i32* null, align 8 +@c = common global i32 0, align 4 +@b = common global i32* null, align 8 + +; Function Attrs: nounwind ssp uwtable +define void @fn() { + store i32* inttoptr (i64 68719476735 to i32*), i32** @a, align 8 + %1 = load i32* @c, align 4 + %2 = sext i32 %1 to i64 + %3 = lshr i64 %2, 12 + %4 = and i64 %3, 68719476735 + %5 = getelementptr inbounds i32* null, i64 %4 + store i32* %5, i32** @b, align 8 + ret void +} |