1
0
mirror of https://github.com/c64scene-ar/llvm-6502.git synced 2025-04-12 07:37:34 +00:00

PR14562 - Truncation of left shift became undef

DAGCombiner::ReduceLoadWidth was converting (trunc i32 (shl i64 v, 32))
into (shl i32 v, 32) into undef. To prevent this, check the shift count
against the final result size.

Patch by: Kevin Schoedel
Reviewed by: Nadav Rotem


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174972 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Paul Redmond 2013-02-12 15:21:21 +00:00
parent 7eacad03ef
commit 5c97450df7
2 changed files with 24 additions and 2 deletions
lib/CodeGen/SelectionDAG
test/CodeGen/X86

@ -5163,8 +5163,15 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
EVT ShImmTy = getShiftAmountTy(Result.getValueType());
if (!isUIntN(ShImmTy.getSizeInBits(), ShLeftAmt))
ShImmTy = VT;
Result = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT,
Result, DAG.getConstant(ShLeftAmt, ShImmTy));
// If the shift amount is as large as the result size (but, presumably,
// no larger than the source) then the useful bits of the result are
// zero; we can't simply return the shortened shift, because the result
// of that operation is undefined.
if (ShLeftAmt >= VT.getSizeInBits())
Result = DAG.getConstant(0, VT);
else
Result = DAG.getNode(ISD::SHL, N0.getDebugLoc(), VT,
Result, DAG.getConstant(ShLeftAmt, ShImmTy));
}
// Return the new loaded value.

@ -0,0 +1,15 @@
; RUN: llc < %s -march=x86 | FileCheck %s
@temp1 = global i64 -77129852189294865, align 8
define void @foo() nounwind {
%x = load i64* @temp1, align 8
%s = shl i64 %x, 32
%t = trunc i64 %s to i32
%z = zext i32 %t to i64
store i64 %z, i64* @temp1, align 8
; CHECK: movl $0, temp1+4
; CHECK: movl $0, temp1
ret void
}