Skip to content

Commit b95047e

Browse files
committed
[DAGCombine] Fix ReduceLoadWidth for shifted offsets
ReduceLoadWidth can trigger using a shifted mask is used and this requires that the function return a shl node to correct for the offset. However, the way that this was implemented meant that the returned result could be an existing node, which would be incorrect. This fixes the method of inserting the new node and replacing uses. Differential Revision: https://reviews.llvm.org/D50432 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351310 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent ad21d2d commit b95047e

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4724,9 +4724,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
47244724
if (SDValue Res = ReduceLoadWidth(N)) {
47254725
LoadSDNode *LN0 = N0->getOpcode() == ISD::ANY_EXTEND
47264726
? cast<LoadSDNode>(N0.getOperand(0)) : cast<LoadSDNode>(N0);
4727-
47284727
AddToWorklist(N);
4729-
CombineTo(LN0, Res, Res.getValue(1));
4728+
DAG.ReplaceAllUsesOfValueWith(SDValue(LN0, 0), Res);
47304729
return SDValue(N, 0);
47314730
}
47324731
}
@@ -9486,18 +9485,15 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) {
94869485
if (DAG.getDataLayout().isBigEndian())
94879486
ShAmt = AdjustBigEndianShift(ShAmt);
94889487

9489-
// We're using a shifted mask, so the load now has an offset. This means we
9490-
// now need to shift right the mask to match the new load and then shift
9491-
// right the result of the AND.
9492-
const APInt &Mask = cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue();
9493-
APInt ShiftedMask = Mask.lshr(ShAmt);
9494-
DAG.UpdateNodeOperands(N, Result, DAG.getConstant(ShiftedMask, DL, VT));
9488+
// We're using a shifted mask, so the load now has an offset. This means
9489+
// that data has been loaded into the lower bytes than it would have been
9490+
// before, so we need to shl the loaded data into the correct position in the
9491+
// register.
94959492
SDValue ShiftC = DAG.getConstant(ShAmt, DL, VT);
9496-
SDValue Shifted = DAG.getNode(ISD::SHL, DL, VT, SDValue(N, 0),
9497-
ShiftC);
9498-
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Shifted);
9499-
DAG.UpdateNodeOperands(Shifted.getNode(), SDValue(N, 0), ShiftC);
9493+
Result = DAG.getNode(ISD::SHL, DL, VT, Result, ShiftC);
9494+
DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result);
95009495
}
9496+
95019497
// Return the new loaded value.
95029498
return Result;
95039499
}

test/CodeGen/ARM/and-load-combine.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,3 +1549,39 @@ define arm_aapcscc i64 @test26(i64* nocapture %p) {
15491549
%and = and i64 %1, -281474976710656
15501550
ret i64 %and
15511551
}
1552+
1553+
; ARM-LABEL: test27:
1554+
; ARM: @ %bb.0:
1555+
; ARM-NEXT: ldrb r1, [r0, #1]
1556+
; ARM-NEXT: lsl r1, r1, #16
1557+
; ARM-NEXT: str r1, [r0]
1558+
; ARM-NEXT: bx lr
1559+
;
1560+
; ARMEB-LABEL: test27:
1561+
; ARMEB: @ %bb.0:
1562+
; ARMEB-NEXT: ldrb r1, [r0, #2]
1563+
; ARMEB-NEXT: lsl r1, r1, #16
1564+
; ARMEB-NEXT: str r1, [r0]
1565+
; ARMEB-NEXT: bx lr
1566+
;
1567+
; THUMB1-LABEL: test27:
1568+
; THUMB1: @ %bb.0:
1569+
; THUMB1-NEXT: ldrb r1, [r0, #1]
1570+
; THUMB1-NEXT: lsls r1, r1, #16
1571+
; THUMB1-NEXT: str r1, [r0]
1572+
; THUMB1-NEXT: bx lr
1573+
;
1574+
; THUMB2-LABEL: test27:
1575+
; THUMB2: @ %bb.0:
1576+
; THUMB2-NEXT: ldrb r1, [r0, #1]
1577+
; THUMB2-NEXT: lsls r1, r1, #16
1578+
; THUMB2-NEXT: str r1, [r0]
1579+
; THUMB2-NEXT: bx lr
1580+
define void @test27(i32* nocapture %ptr) {
1581+
entry:
1582+
%0 = load i32, i32* %ptr, align 4
1583+
%and = and i32 %0, 65280
1584+
%shl = shl i32 %and, 8
1585+
store i32 %shl, i32* %ptr, align 4
1586+
ret void
1587+
}

0 commit comments

Comments
 (0)