Skip to content

Commit

Permalink
Fix PR16360
Browse files Browse the repository at this point in the history
When (srl (anyextend x), c) is folded into (anyextend (srl x, c)), the
high bits are not cleared. Add 'and' to clear off them.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184575 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
hliao2 committed Jun 21, 2013
1 parent c12c880 commit 2da8639
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3915,8 +3915,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
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();
Expand All @@ -3929,7 +3928,10 @@ SDValue DAGCombiner::visitSRL(SDNode *N) {
N0.getOperand(0),
DAG.getConstant(ShiftAmt, getShiftAmountTy(SmallVT)));
AddToWorkList(SmallShift.getNode());
return DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), VT, SmallShift);
APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits()).lshr(ShiftAmt);
return DAG.getNode(ISD::AND, SDLoc(N), VT,
DAG.getNode(ISD::ANY_EXTEND, SDLoc(N), VT, SmallShift),
DAG.getConstant(Mask, VT));
}
}

Expand Down
16 changes: 16 additions & 0 deletions test/CodeGen/X86/pr16360.ll
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 2da8639

Please sign in to comment.