From 6bb4958543e2b7ff412b3dac3ebf01a184193ad7 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sat, 23 May 2009 17:29:48 +0000 Subject: [PATCH] Fix PR4254. The DAGCombiner created a negative shiftamount, stored in an unsigned variable. Later the optimizer eliminated the shift entirely as being undefined. Example: (srl (shl X, 56) 48). ShiftAmt is 4294967288. Fix it by checking that the shiftamount is positive, and storing in a signed variable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72331 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 ++-- test/CodeGen/X86/2009-05-23-dagcombine-shifts.ll | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/X86/2009-05-23-dagcombine-shifts.ll diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 6e0cc9f60a2..a866cb5629e 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2546,13 +2546,13 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { MVT TruncVT = MVT::getIntegerVT(VTValSize - N1C->getZExtValue()); // Determine the residual right-shift amount. - unsigned ShiftAmt = N1C->getZExtValue() - N01C->getZExtValue(); + signed ShiftAmt = N1C->getZExtValue() - N01C->getZExtValue(); // If the shift is not a no-op (in which case this should be just a sign // extend already), the truncated to type is legal, sign_extend is legal // on that type, and the the truncate to that type is both legal and free, // perform the transform. - if (ShiftAmt && + if ((ShiftAmt > 0) && TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND, TruncVT) && TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) && TLI.isTruncateFree(VT, TruncVT)) { diff --git a/test/CodeGen/X86/2009-05-23-dagcombine-shifts.ll b/test/CodeGen/X86/2009-05-23-dagcombine-shifts.ll new file mode 100644 index 00000000000..6f2bef4fca1 --- /dev/null +++ b/test/CodeGen/X86/2009-05-23-dagcombine-shifts.ll @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | llc | grep -E {sar|shl|mov|or} | count 4 +; Check that the shr(shl X, 56), 48) is not mistakenly turned into +; a shr (X, -8) that gets subsequently "optimized away" as undef +; PR4254 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define i64 @foo(i64 %b) nounwind readnone { +entry: + %shl = shl i64 %b, 56 ; [#uses=1] + %shr = ashr i64 %shl, 48 ; [#uses=1] + %add5 = or i64 %shr, 1 ; [#uses=1] + ret i64 %add5 +} -- 2.34.1