Skip to content

Commit eeb9aaa

Browse files
committed
[SelectionDAG] Combine range metadata when loads are CSEd.
When CSEing a load with an existing load with different range metadata, clear the range metadata on the existing load. This is conservative, alternatively we could calculate new range metadata using getMostGenericRange. Without a test case I wasn't sure it was worth it. getMostGenericRange takes a non-const MDNode*, but all of SelectionDAG uses const MDNode*. A const_cast will need to be used somewhere or we need to make the code base consistent about whether MDNode pointers should be const or not. I'm sure this isn't the only place that needs to be updated to handle the CSE. Fixes #145363.
1 parent 81eb3be commit eeb9aaa

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

llvm/include/llvm/CodeGen/SelectionDAGNodes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,14 @@ class MemSDNode : public SDNode {
14971497
MMO->refineAlignment(NewMMO);
14981498
}
14991499

1500+
void refineRanges(const MachineMemOperand *NewMMO) {
1501+
// If this node has range metadata that is different than NewMMO, clear the
1502+
// range metadata.
1503+
// FIXME: Union the ranges instead?
1504+
if (getRanges() && getRanges() != NewMMO->getRanges())
1505+
MMO->clearRanges();
1506+
}
1507+
15001508
const SDValue &getChain() const { return getOperand(0); }
15011509

15021510
const SDValue &getBasePtr() const {

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,8 @@ SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N) {
12751275
// to replace the dead one with the existing one. This can cause
12761276
// recursive merging of other unrelated nodes down the line.
12771277
Existing->intersectFlagsWith(N->getFlags());
1278+
if (auto *MemNode = dyn_cast<MemSDNode>(Existing))
1279+
MemNode->refineRanges(cast<MemSDNode>(N)->getMemOperand());
12781280
ReplaceAllUsesWith(N, Existing);
12791281

12801282
// N is now dead. Inform the listeners and delete it.
@@ -9109,8 +9111,9 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
91099111
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
91109112
ID.AddInteger(MMO->getFlags());
91119113
void* IP = nullptr;
9112-
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
9113-
cast<AtomicSDNode>(E)->refineAlignment(MMO);
9114+
if (auto *E = cast_or_null<AtomicSDNode>(FindNodeOrInsertPos(ID, dl, IP))) {
9115+
E->refineAlignment(MMO);
9116+
E->refineRanges(MMO);
91149117
return SDValue(E, 0);
91159118
}
91169119

@@ -9401,8 +9404,9 @@ SDValue SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
94019404
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
94029405
ID.AddInteger(MMO->getFlags());
94039406
void *IP = nullptr;
9404-
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
9405-
cast<LoadSDNode>(E)->refineAlignment(MMO);
9407+
if (auto *E = cast_or_null<LoadSDNode>(FindNodeOrInsertPos(ID, dl, IP))) {
9408+
E->refineAlignment(MMO);
9409+
E->refineRanges(MMO);
94069410
return SDValue(E, 0);
94079411
}
94089412
auto *N = newSDNode<LoadSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs, AM,
@@ -9622,8 +9626,9 @@ SDValue SelectionDAG::getLoadVP(ISD::MemIndexedMode AM,
96229626
ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
96239627
ID.AddInteger(MMO->getFlags());
96249628
void *IP = nullptr;
9625-
if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
9626-
cast<VPLoadSDNode>(E)->refineAlignment(MMO);
9629+
if (auto *E = cast_or_null<VPLoadSDNode>(FindNodeOrInsertPos(ID, dl, IP))) {
9630+
E->refineAlignment(MMO);
9631+
E->refineRanges(MMO);
96279632
return SDValue(E, 0);
96289633
}
96299634
auto *N = newSDNode<VPLoadSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs, AM,

llvm/test/CodeGen/RISCV/pr145363.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ define i32 @f(ptr %p) {
99
; CHECK-NEXT: lw a0, 0(a0)
1010
; CHECK-NEXT: lui a1, 294471
1111
; CHECK-NEXT: addi a1, a1, 1064
12-
; CHECK-NEXT: or a0, a0, a1
12+
; CHECK-NEXT: addw a0, a0, a1
1313
; CHECK-NEXT: ret
1414
%load = load i32, ptr %p, align 4, !range !0
1515
%load2 = load i32, ptr %p, align 4
@@ -25,7 +25,7 @@ define i32 @test(ptr %p, i32 %x, ptr %q) {
2525
; CHECK-NEXT: lw a1, 0(a0)
2626
; CHECK-NEXT: lui a0, 294471
2727
; CHECK-NEXT: addi a0, a0, 1064
28-
; CHECK-NEXT: or a0, a1, a0
28+
; CHECK-NEXT: addw a0, a1, a0
2929
; CHECK-NEXT: sw a1, 0(a2)
3030
; CHECK-NEXT: ret
3131
%load = load i32, ptr %p, align 4, !range !0

0 commit comments

Comments
 (0)