53 lines
2.0 KiB
Diff
53 lines
2.0 KiB
Diff
This patch needs to be applied to LLVM 3.2/3.3 (but was verified with 3.3 only) to
|
|
fix a problem with shift instructions on x86 (see PR16360 in LLVM bugzilla).
|
|
This is general LLVM problem, which triggers on one of x86 tests in out test suit.
|
|
LLVM 3.4 contains this fix (r184575).
|
|
|
|
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
|
|
===================================================================
|
|
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp (revision 183970)
|
|
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp (working copy)
|
|
@@ -3901,8 +3901,7 @@
|
|
DAG.getConstant(~0ULL >> ShAmt, VT));
|
|
}
|
|
|
|
-
|
|
- // fold (srl (anyextend x), c) -> (anyextend (srl x, c))
|
|
+ // fold (srl (anyextend x), c) -> (and (anyextend (srl x, c)), mask)
|
|
if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
|
|
// Shifting in all undef bits?
|
|
EVT SmallVT = N0.getOperand(0).getValueType();
|
|
@@ -3915,7 +3914,10 @@
|
|
N0.getOperand(0),
|
|
DAG.getConstant(ShiftAmt, getShiftAmountTy(SmallVT)));
|
|
AddToWorkList(SmallShift.getNode());
|
|
- return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, SmallShift);
|
|
+ APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits()).lshr(ShiftAmt);
|
|
+ return DAG.getNode(ISD::AND, N->getDebugLoc(), VT,
|
|
+ DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, SmallShift),
|
|
+ DAG.getConstant(Mask, VT));
|
|
}
|
|
}
|
|
|
|
Index: test/CodeGen/X86/pr16360.ll
|
|
===================================================================
|
|
--- test/CodeGen/X86/pr16360.ll (revision 0)
|
|
+++ test/CodeGen/X86/pr16360.ll (revision 0)
|
|
@@ -0,0 +1,16 @@
|
|
+; RUN: llc < %s -mtriple=i686-pc-linux | FileCheck %s
|
|
+
|
|
+define i64 @foo(i32 %sum) {
|
|
+entry:
|
|
+ %conv = sext i32 %sum to i64
|
|
+ %shr = lshr i64 %conv, 2
|
|
+ %or = or i64 4611686018360279040, %shr
|
|
+ ret i64 %or
|
|
+}
|
|
+
|
|
+; CHECK: foo
|
|
+; CHECK: shrl $2
|
|
+; CHECK: orl $-67108864
|
|
+; CHECK-NOT: movl $-1
|
|
+; CHECK: movl $1073741823
|
|
+; CHECK: ret
|