Skip to content

Commit f261f14

Browse files
authored
[SelectionDAG][RISCV] Teach computeKnownBits to use range metadata for atomic_load. (#137119)
And teach SelectionDAGBuilder to get the range metadata in visitAtomicLoad. This allows us to recognize that sign extending a byte load of a boolean value from memory will produce zeros for the extended bits. This allow us to remove an AND on RISC-V. Tests copied from #136502 with range metadata added to i1 cases. Some of the test effects overlap with #136502, but that patch can't handle the acquire or seq_cst cases with the Zalasr extension. We only have sign extending versions of those loads.
1 parent c8dc3ed commit f261f14

File tree

3 files changed

+1403
-11
lines changed

3 files changed

+1403
-11
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4382,6 +4382,43 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
43824382
Known.Zero |= APInt::getBitsSetFrom(BitWidth, VT.getScalarSizeInBits());
43834383
break;
43844384
}
4385+
case ISD::ATOMIC_LOAD: {
4386+
// If we are looking at the loaded value.
4387+
if (Op.getResNo() == 0) {
4388+
auto *AT = cast<AtomicSDNode>(Op);
4389+
unsigned ScalarMemorySize = AT->getMemoryVT().getScalarSizeInBits();
4390+
KnownBits KnownScalarMemory(ScalarMemorySize);
4391+
if (const MDNode *MD = AT->getRanges())
4392+
computeKnownBitsFromRangeMetadata(*MD, KnownScalarMemory);
4393+
4394+
switch (AT->getExtensionType()) {
4395+
case ISD::ZEXTLOAD:
4396+
Known = KnownScalarMemory.zext(BitWidth);
4397+
break;
4398+
case ISD::SEXTLOAD:
4399+
Known = KnownScalarMemory.sext(BitWidth);
4400+
break;
4401+
case ISD::EXTLOAD:
4402+
switch (TLI->getExtendForAtomicOps()) {
4403+
case ISD::ZERO_EXTEND:
4404+
Known = KnownScalarMemory.zext(BitWidth);
4405+
break;
4406+
case ISD::SIGN_EXTEND:
4407+
Known = KnownScalarMemory.sext(BitWidth);
4408+
break;
4409+
default:
4410+
Known = KnownScalarMemory.anyext(BitWidth);
4411+
break;
4412+
}
4413+
break;
4414+
case ISD::NON_EXTLOAD:
4415+
Known = KnownScalarMemory;
4416+
break;
4417+
}
4418+
assert(Known.getBitWidth() == BitWidth);
4419+
}
4420+
break;
4421+
}
43854422
case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
43864423
if (Op.getResNo() == 1) {
43874424
// The boolean result conforms to getBooleanContents.
@@ -4407,21 +4444,13 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
44074444
case ISD::ATOMIC_LOAD_MIN:
44084445
case ISD::ATOMIC_LOAD_MAX:
44094446
case ISD::ATOMIC_LOAD_UMIN:
4410-
case ISD::ATOMIC_LOAD_UMAX:
4411-
case ISD::ATOMIC_LOAD: {
4447+
case ISD::ATOMIC_LOAD_UMAX: {
44124448
// If we are looking at the loaded value.
44134449
if (Op.getResNo() == 0) {
44144450
auto *AT = cast<AtomicSDNode>(Op);
44154451
unsigned MemBits = AT->getMemoryVT().getScalarSizeInBits();
44164452

4417-
// For atomic_load, prefer to use the extension type.
4418-
if (Op->getOpcode() == ISD::ATOMIC_LOAD) {
4419-
if (AT->getExtensionType() == ISD::ZEXTLOAD)
4420-
Known.Zero.setBitsFrom(MemBits);
4421-
else if (AT->getExtensionType() != ISD::SEXTLOAD &&
4422-
TLI->getExtendForAtomicOps() == ISD::ZERO_EXTEND)
4423-
Known.Zero.setBitsFrom(MemBits);
4424-
} else if (TLI->getExtendForAtomicOps() == ISD::ZERO_EXTEND)
4453+
if (TLI->getExtendForAtomicOps() == ISD::ZERO_EXTEND)
44254454
Known.Zero.setBitsFrom(MemBits);
44264455
}
44274456
break;

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5150,9 +5150,10 @@ void SelectionDAGBuilder::visitAtomicLoad(const LoadInst &I) {
51505150

51515151
auto Flags = TLI.getLoadMemOperandFlags(I, DAG.getDataLayout(), AC, LibInfo);
51525152

5153+
const MDNode *Ranges = getRangeMetadata(I);
51535154
MachineMemOperand *MMO = DAG.getMachineFunction().getMachineMemOperand(
51545155
MachinePointerInfo(I.getPointerOperand()), Flags, MemVT.getStoreSize(),
5155-
I.getAlign(), AAMDNodes(), nullptr, SSID, Order);
5156+
I.getAlign(), AAMDNodes(), Ranges, SSID, Order);
51565157

51575158
InChain = TLI.prepareVolatileOrAtomicLoad(InChain, dl, DAG);
51585159

0 commit comments

Comments
 (0)