summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuergen Ributzka <juergen@apple.com>2014-02-06 04:09:06 +0000
committerJuergen Ributzka <juergen@apple.com>2014-02-06 04:09:06 +0000
commit58bc0ca37b66bf49bc20661fd2748319a06808c3 (patch)
tree8eeca97141e70f357a7aca2a01af8b3f85f86528
parentc7ac256d525988388c79c8c821a6c2e5d144ae68 (diff)
downloadllvm-58bc0ca37b66bf49bc20661fd2748319a06808c3.tar.gz
llvm-58bc0ca37b66bf49bc20661fd2748319a06808c3.tar.bz2
llvm-58bc0ca37b66bf49bc20661fd2748319a06808c3.tar.xz
[DAG] Don't pull the binary operation though the shift if the operands have opaque constants.
During DAGCombine visitShiftByConstant assumes that certain binary operations with only constant operands can always be folded successfully. This is no longer true when the constant is opaque. This commit fixes visitShiftByConstant by not performing the optimization for opaque constants. Otherwise we would end up in an infinite DAGCombine loop. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200900 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp11
-rw-r--r--test/CodeGen/Generic/2014-02-05-OpaqueConstants.ll19
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
+}