Skip to content

Commit 06fa477

Browse files
committed
Preserve multiple set assembler behavior with assembler-only handling
1 parent 84e786c commit 06fa477

File tree

7 files changed

+112
-80
lines changed

7 files changed

+112
-80
lines changed

llvm/lib/Target/AMDGPU/AMDGPU.td

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,19 @@ def FeatureSetPrioIncWgInst : SubtargetFeature<"setprio-inc-wg-inst",
12381238
// Subtarget Features (options and debugging)
12391239
//===------------------------------------------------------------===//
12401240

1241+
// Ugly hack to accomodate an assembling modules with mixed
1242+
// wavesizes. Ideally we would have a mapping symbol in assembly which
1243+
// would keep track of which sections of code should be treated as
1244+
// wave32 and wave64. Instead what users do is assemble with both
1245+
// wavesizes enabled. We translate this into this special mode so this
1246+
// only influences assembler behavior and nothing else.
1247+
def FeatureAssemblerPermissiveWavesize : SubtargetFeature<
1248+
"assembler-permissive-wavesize",
1249+
"AssemblerPermissiveWavesize",
1250+
"true",
1251+
"allow parsing wave32 and wave64 variants of instructions"
1252+
>;
1253+
12411254
class FeatureMaxPrivateElementSize<int size> : SubtargetFeature<
12421255
"max-private-element-size-"#size,
12431256
"MaxPrivateElementSize",

llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,12 @@ raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
12471247
// AsmParser
12481248
//===----------------------------------------------------------------------===//
12491249

1250+
// TODO: define GET_SUBTARGET_FEATURE_NAME
1251+
#define GET_REGISTER_MATCHER
1252+
#include "AMDGPUGenAsmMatcher.inc"
1253+
#undef GET_REGISTER_MATCHER
1254+
#undef GET_SUBTARGET_FEATURE_NAME
1255+
12501256
// Holds info related to the current kernel, e.g. count of SGPRs used.
12511257
// Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
12521258
// .amdgpu_hsa_kernel or at EOF.
@@ -1537,6 +1543,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
15371543
return AMDGPU::isGFX10_BEncoding(getSTI());
15381544
}
15391545

1546+
bool isWave32() const { return getAvailableFeatures()[Feature_isWave32Bit]; }
1547+
1548+
bool isWave64() const { return getAvailableFeatures()[Feature_isWave64Bit]; }
1549+
15401550
bool hasInv2PiInlineImm() const {
15411551
return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
15421552
}
@@ -1600,6 +1610,8 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
16001610
return &MII;
16011611
}
16021612

1613+
// FIXME: This should not be used. Instead, should use queries derived from
1614+
// getAvailableFeatures().
16031615
const FeatureBitset &getFeatureBits() const {
16041616
return getSTI().getFeatureBits();
16051617
}
@@ -2256,9 +2268,8 @@ bool AMDGPUOperand::isSDWAInt32Operand() const {
22562268
}
22572269

22582270
bool AMDGPUOperand::isBoolReg() const {
2259-
auto FB = AsmParser->getFeatureBits();
2260-
return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2261-
(FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2271+
return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2272+
(AsmParser->isWave32() && isSCSrc_b32()));
22622273
}
22632274

22642275
uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val, unsigned Size) const
@@ -4977,9 +4988,8 @@ bool AMDGPUAsmParser::validateDPP(const MCInst &Inst,
49774988

49784989
// Check if VCC register matches wavefront size
49794990
bool AMDGPUAsmParser::validateVccOperand(MCRegister Reg) const {
4980-
auto FB = getFeatureBits();
4981-
return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4982-
(FB[AMDGPU::FeatureWavefrontSize32] && Reg == AMDGPU::VCC_LO);
4991+
return (Reg == AMDGPU::VCC && isWave64()) ||
4992+
(Reg == AMDGPU::VCC_LO && isWave32());
49834993
}
49844994

49854995
// One unique literal can be used. VOP3 literal is only allowed in GFX10+
@@ -5663,7 +5673,7 @@ bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
56635673
// Check if this instruction may be used with a different wavesize.
56645674
if (isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
56655675
!getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5666-
5676+
// FIXME: Use getAvailableFeatures, and do not manually recompute
56675677
FeatureBitset FeaturesWS32 = getFeatureBits();
56685678
FeaturesWS32.flip(AMDGPU::FeatureWavefrontSize64)
56695679
.flip(AMDGPU::FeatureWavefrontSize32);
@@ -6418,10 +6428,10 @@ bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
64186428
if (C.code_properties & AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32) {
64196429
if (!isGFX10Plus())
64206430
return TokError("enable_wavefront_size32=1 is only allowed on GFX10+");
6421-
if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6431+
if (!isWave32())
64226432
return TokError("enable_wavefront_size32=1 requires +WavefrontSize32");
64236433
} else {
6424-
if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6434+
if (!isWave64())
64256435
return TokError("enable_wavefront_size32=0 requires +WavefrontSize64");
64266436
}
64276437
}
@@ -6430,10 +6440,10 @@ bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
64306440
if (C.wavefront_size == 5) {
64316441
if (!isGFX10Plus())
64326442
return TokError("wavefront_size=5 is only allowed on GFX10+");
6433-
if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6443+
if (!isWave32())
64346444
return TokError("wavefront_size=5 requires +WavefrontSize32");
64356445
} else if (C.wavefront_size == 6) {
6436-
if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6446+
if (!isWave64())
64376447
return TokError("wavefront_size=6 requires +WavefrontSize64");
64386448
}
64396449
}
@@ -10336,7 +10346,6 @@ LLVMInitializeAMDGPUAsmParser() {
1033610346
RegisterMCAsmParser<AMDGPUAsmParser> B(getTheGCNTarget());
1033710347
}
1033810348

10339-
#define GET_REGISTER_MATCHER
1034010349
#define GET_MATCHER_IMPLEMENTATION
1034110350
#define GET_MNEMONIC_SPELL_CHECKER
1034210351
#define GET_MNEMONIC_CHECKER

llvm/lib/Target/AMDGPU/GCNSubtarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
9999
bool EnableDS128 = false;
100100
bool EnablePRTStrictNull = false;
101101
bool DumpCode = false;
102+
bool AssemblerPermissiveWavesize = false;
102103

103104
// Subtarget statically properties set by tablegen
104105
bool FP64 = false;

llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCTargetDesc.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,14 @@ createAMDGPUMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) {
9898
: AMDGPU::FeatureWavefrontSize64);
9999
} else if (IsWave64 && IsWave32) {
100100
// The wave size is mutually exclusive. If both somehow end up set, wave64
101-
// wins.
102-
//
103-
// FIXME: This should really just be an error.
104-
STI->ToggleFeature(AMDGPU::FeatureWavefrontSize32);
101+
// wins if supported.
102+
STI->ToggleFeature(AMDGPU::supportsWave32(*STI)
103+
? AMDGPU::FeatureWavefrontSize64
104+
: AMDGPU::FeatureWavefrontSize32);
105+
106+
// If both wavesizes were manually requested, hack in a feature to permit
107+
// assembling modules with mixed wavesizes.
108+
STI->ToggleFeature(AMDGPU::FeatureAssemblerPermissiveWavesize);
105109
}
106110

107111
assert((STI->hasFeature(AMDGPU::FeatureWavefrontSize64) !=

llvm/lib/Target/AMDGPU/SIInstrInfo.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
//===----------------------------------------------------------------------===//
88

99
def isWave32 : Predicate<"Subtarget->isWave32()">,
10-
AssemblerPredicate <(all_of FeatureWavefrontSize32)>;
10+
AssemblerPredicate <(any_of FeatureWavefrontSize32,
11+
FeatureAssemblerPermissiveWavesize)>;
1112
def isWave64 : Predicate<"Subtarget->isWave64()">,
12-
AssemblerPredicate <(all_of FeatureWavefrontSize64)>;
13+
AssemblerPredicate <(any_of FeatureWavefrontSize64,
14+
FeatureAssemblerPermissiveWavesize)>;
1315

1416
class AMDGPUMnemonicAlias<string From, string To, string VariantName = "">
1517
: MnemonicAlias<From, To, VariantName>, PredicateControl;

llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,6 +1568,11 @@ bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI);
15681568
bool hasMAIInsts(const MCSubtargetInfo &STI);
15691569
bool hasVOPD(const MCSubtargetInfo &STI);
15701570
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI);
1571+
1572+
bool supportsWave32(const MCSubtargetInfo &STI) {
1573+
return AMDGPU::isGFX10Plus(STI) && !AMDGPU::isGFX1250(STI);
1574+
}
1575+
15711576
int getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR);
15721577
unsigned hasKernargPreload(const MCSubtargetInfo &STI);
15731578
bool hasSMRDSignedImmOffset(const MCSubtargetInfo &ST);

0 commit comments

Comments
 (0)