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:
parent
7eacad03ef
commit
5c97450df7
@ -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.
|
||||
|
15
test/CodeGen/X86/pr14562.ll
Normal file
15
test/CodeGen/X86/pr14562.ll
Normal file
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user