Skip to content

Commit a26bd4e

Browse files
committed
[TableGen] Support combining AssemblerPredicates with ORs
For context, the proposed RISC-V bit manipulation extension has a subset of instructions which require one of two SubtargetFeatures to be enabled, 'zbb' or 'zbp', and there is no defined feature which both of these can imply to use as a constraint either (see comments in D65649). AssemblerPredicates allow multiple SubtargetFeatures to be declared in the "AssemblerCondString" field, separated by commas, and this means that the two features must both be enabled. There is no equivalent to say that _either_ feature X or feature Y must be enabled, short of creating a dummy SubtargetFeature for this purpose and having features X and Y imply the new feature. To solve the case where X or Y is needed without adding a new feature, and to better match a typical TableGen style, this replaces the existing "AssemblerCondString" with a dag "AssemblerCondDag" which represents the same information. Two operators are defined for use with AssemblerCondDag, "all_of", which matches the current behaviour, and "any_of", which adds the new proposed ORing features functionality. This was originally proposed in the RFC at http://lists.llvm.org/pipermail/llvm-dev/2020-February/139138.html Changes to all current backends are mechanical to support the replaced functionality, and are NFCI. At this stage, it is illegal to combine features with ands and ors in a single AssemblerCondDag. I suspect this case is sufficiently rare that adding more complex changes to support it are unnecessary. Differential Revision: https://reviews.llvm.org/D74338
1 parent 20e36f3 commit a26bd4e

27 files changed

+768
-455
lines changed

llvm/include/llvm/MC/MCInstPrinter.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,17 @@ struct AliasPattern {
129129

130130
struct AliasPatternCond {
131131
enum CondKind : uint8_t {
132-
K_Feature, // Match only if a feature is enabled.
133-
K_NegFeature, // Match only if a feature is disabled.
134-
K_Ignore, // Match any operand.
135-
K_Reg, // Match a specific register.
136-
K_TiedReg, // Match another already matched register.
137-
K_Imm, // Match a specific immediate.
138-
K_RegClass, // Match registers in a class.
139-
K_Custom, // Call custom matcher by index.
132+
K_Feature, // Match only if a feature is enabled.
133+
K_NegFeature, // Match only if a feature is disabled.
134+
K_OrFeature, // Match only if one of a set of features is enabled.
135+
K_OrNegFeature, // Match only if one of a set of features is disabled.
136+
K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
137+
K_Ignore, // Match any operand.
138+
K_Reg, // Match a specific register.
139+
K_TiedReg, // Match another already matched register.
140+
K_Imm, // Match a specific immediate.
141+
K_RegClass, // Match registers in a class.
142+
K_Custom, // Call custom matcher by index.
140143
};
141144

142145
CondKind Kind;

llvm/include/llvm/Target/Target.td

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,21 @@ class Predicate<string cond> {
664664
/// feature from the AssemblerPredicate class in addition to Predicate.
665665
bit AssemblerMatcherPredicate = 0;
666666

667-
/// AssemblerCondString - Name of the subtarget feature being tested used
668-
/// as alternative condition string used for assembler matcher.
669-
/// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0".
670-
/// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0".
671-
/// It can also list multiple features separated by ",".
672-
/// e.g. "ModeThumb,FeatureThumb2" is translated to
667+
/// AssemblerCondDag - Set of subtarget features being tested used
668+
/// as alternative condition string used for assembler matcher. Must be used
669+
/// with (all_of) to indicate that all features must be present, or (any_of)
670+
/// to indicate that at least one must be. The required lack of presence of
671+
/// a feature can be tested using a (not) node including the feature.
672+
/// e.g. "(all_of ModeThumb)" is translated to "(Bits & ModeThumb) != 0".
673+
/// "(all_of (not ModeThumb))" is translated to
674+
/// "(Bits & ModeThumb) == 0".
675+
/// "(all_of ModeThumb, FeatureThumb2)" is translated to
673676
/// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
674-
string AssemblerCondString = "";
677+
/// "(any_of ModeTumb, FeatureThumb2)" is translated to
678+
/// "(Bits & ModeThumb) != 0 || (Bits & FeatureThumb2) != 0".
679+
/// all_of and any_of cannot be combined in a single dag, instead multiple
680+
/// predicates can be placed onto Instruction definitions.
681+
dag AssemblerCondDag;
675682

676683
/// PredicateName - User-level name to use for the predicate. Mainly for use
677684
/// in diagnostics such as missing feature errors in the asm matcher.
@@ -1352,11 +1359,15 @@ class AsmParserVariant {
13521359
}
13531360
def DefaultAsmParserVariant : AsmParserVariant;
13541361

1362+
// Operators for combining SubtargetFeatures in AssemblerPredicates
1363+
def any_of;
1364+
def all_of;
1365+
13551366
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
13561367
/// matches instructions and aliases.
1357-
class AssemblerPredicate<string cond, string name = ""> {
1368+
class AssemblerPredicate<dag cond, string name = ""> {
13581369
bit AssemblerMatcherPredicate = 1;
1359-
string AssemblerCondString = cond;
1370+
dag AssemblerCondDag = cond;
13601371
string PredicateName = name;
13611372
}
13621373

llvm/lib/MC/MCInstPrinter.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,29 @@ void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) {
6262
static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
6363
const MCRegisterInfo &MRI, unsigned &OpIdx,
6464
const AliasMatchingData &M,
65-
const AliasPatternCond &C) {
65+
const AliasPatternCond &C,
66+
bool &OrPredicateResult) {
6667
// Feature tests are special, they don't consume operands.
6768
if (C.Kind == AliasPatternCond::K_Feature)
6869
return STI->getFeatureBits().test(C.Value);
6970
if (C.Kind == AliasPatternCond::K_NegFeature)
7071
return !STI->getFeatureBits().test(C.Value);
72+
// For feature tests where just one feature is required in a list, set the
73+
// predicate result bit to whether the expression will return true, and only
74+
// return the real result at the end of list marker.
75+
if (C.Kind == AliasPatternCond::K_OrFeature) {
76+
OrPredicateResult |= STI->getFeatureBits().test(C.Value);
77+
return true;
78+
}
79+
if (C.Kind == AliasPatternCond::K_OrNegFeature) {
80+
OrPredicateResult |= !(STI->getFeatureBits().test(C.Value));
81+
return true;
82+
}
83+
if (C.Kind == AliasPatternCond::K_EndOrFeatures) {
84+
bool Res = OrPredicateResult;
85+
OrPredicateResult = false;
86+
return Res;
87+
}
7188

7289
// Get and consume an operand.
7390
const MCOperand &Opnd = MI.getOperand(OpIdx);
@@ -95,6 +112,9 @@ static bool matchAliasCondition(const MCInst &MI, const MCSubtargetInfo *STI,
95112
return true;
96113
case AliasPatternCond::K_Feature:
97114
case AliasPatternCond::K_NegFeature:
115+
case AliasPatternCond::K_OrFeature:
116+
case AliasPatternCond::K_OrNegFeature:
117+
case AliasPatternCond::K_EndOrFeatures:
98118
llvm_unreachable("handled earlier");
99119
}
100120
llvm_unreachable("invalid kind");
@@ -125,8 +145,10 @@ const char *MCInstPrinter::matchAliasPatterns(const MCInst *MI,
125145
ArrayRef<AliasPatternCond> Conds =
126146
M.PatternConds.slice(P.AliasCondStart, P.NumConds);
127147
unsigned OpIdx = 0;
148+
bool OrPredicateResult = false;
128149
if (llvm::all_of(Conds, [&](const AliasPatternCond &C) {
129-
return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C);
150+
return matchAliasCondition(*MI, STI, MRI, OpIdx, M, C,
151+
OrPredicateResult);
130152
})) {
131153
// If all conditions matched, use this asm string.
132154
AsmStrOffset = P.AsmStrOffset;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -14,142 +14,142 @@
1414
// ARM Instruction Predicate Definitions.
1515
//
1616
def HasV8_1a : Predicate<"Subtarget->hasV8_1aOps()">,
17-
AssemblerPredicate<"HasV8_1aOps", "armv8.1a">;
17+
AssemblerPredicate<(all_of HasV8_1aOps), "armv8.1a">;
1818
def HasV8_2a : Predicate<"Subtarget->hasV8_2aOps()">,
19-
AssemblerPredicate<"HasV8_2aOps", "armv8.2a">;
19+
AssemblerPredicate<(all_of HasV8_2aOps), "armv8.2a">;
2020
def HasV8_3a : Predicate<"Subtarget->hasV8_3aOps()">,
21-
AssemblerPredicate<"HasV8_3aOps", "armv8.3a">;
21+
AssemblerPredicate<(all_of HasV8_3aOps), "armv8.3a">;
2222
def HasV8_4a : Predicate<"Subtarget->hasV8_4aOps()">,
23-
AssemblerPredicate<"HasV8_4aOps", "armv8.4a">;
23+
AssemblerPredicate<(all_of HasV8_4aOps), "armv8.4a">;
2424
def HasV8_5a : Predicate<"Subtarget->hasV8_5aOps()">,
25-
AssemblerPredicate<"HasV8_5aOps", "armv8.5a">;
25+
AssemblerPredicate<(all_of HasV8_5aOps), "armv8.5a">;
2626
def HasVH : Predicate<"Subtarget->hasVH()">,
27-
AssemblerPredicate<"FeatureVH", "vh">;
27+
AssemblerPredicate<(all_of FeatureVH), "vh">;
2828

2929
def HasLOR : Predicate<"Subtarget->hasLOR()">,
30-
AssemblerPredicate<"FeatureLOR", "lor">;
30+
AssemblerPredicate<(all_of FeatureLOR), "lor">;
3131

3232
def HasPA : Predicate<"Subtarget->hasPA()">,
33-
AssemblerPredicate<"FeaturePA", "pa">;
33+
AssemblerPredicate<(all_of FeaturePA), "pa">;
3434

3535
def HasJS : Predicate<"Subtarget->hasJS()">,
36-
AssemblerPredicate<"FeatureJS", "jsconv">;
36+
AssemblerPredicate<(all_of FeatureJS), "jsconv">;
3737

3838
def HasCCIDX : Predicate<"Subtarget->hasCCIDX()">,
39-
AssemblerPredicate<"FeatureCCIDX", "ccidx">;
39+
AssemblerPredicate<(all_of FeatureCCIDX), "ccidx">;
4040

4141
def HasComplxNum : Predicate<"Subtarget->hasComplxNum()">,
42-
AssemblerPredicate<"FeatureComplxNum", "complxnum">;
42+
AssemblerPredicate<(all_of FeatureComplxNum), "complxnum">;
4343

4444
def HasNV : Predicate<"Subtarget->hasNV()">,
45-
AssemblerPredicate<"FeatureNV", "nv">;
45+
AssemblerPredicate<(all_of FeatureNV), "nv">;
4646

4747
def HasRASv8_4 : Predicate<"Subtarget->hasRASv8_4()">,
48-
AssemblerPredicate<"FeatureRASv8_4", "rasv8_4">;
48+
AssemblerPredicate<(all_of FeatureRASv8_4), "rasv8_4">;
4949

5050
def HasMPAM : Predicate<"Subtarget->hasMPAM()">,
51-
AssemblerPredicate<"FeatureMPAM", "mpam">;
51+
AssemblerPredicate<(all_of FeatureMPAM), "mpam">;
5252

5353
def HasDIT : Predicate<"Subtarget->hasDIT()">,
54-
AssemblerPredicate<"FeatureDIT", "dit">;
54+
AssemblerPredicate<(all_of FeatureDIT), "dit">;
5555

5656
def HasTRACEV8_4 : Predicate<"Subtarget->hasTRACEV8_4()">,
57-
AssemblerPredicate<"FeatureTRACEV8_4", "tracev8.4">;
57+
AssemblerPredicate<(all_of FeatureTRACEV8_4), "tracev8.4">;
5858

5959
def HasAM : Predicate<"Subtarget->hasAM()">,
60-
AssemblerPredicate<"FeatureAM", "am">;
60+
AssemblerPredicate<(all_of FeatureAM), "am">;
6161

6262
def HasSEL2 : Predicate<"Subtarget->hasSEL2()">,
63-
AssemblerPredicate<"FeatureSEL2", "sel2">;
63+
AssemblerPredicate<(all_of FeatureSEL2), "sel2">;
6464

6565
def HasPMU : Predicate<"Subtarget->hasPMU()">,
66-
AssemblerPredicate<"FeaturePMU", "pmu">;
66+
AssemblerPredicate<(all_of FeaturePMU), "pmu">;
6767

6868
def HasTLB_RMI : Predicate<"Subtarget->hasTLB_RMI()">,
69-
AssemblerPredicate<"FeatureTLB_RMI", "tlb-rmi">;
69+
AssemblerPredicate<(all_of FeatureTLB_RMI), "tlb-rmi">;
7070

7171
def HasFMI : Predicate<"Subtarget->hasFMI()">,
72-
AssemblerPredicate<"FeatureFMI", "fmi">;
72+
AssemblerPredicate<(all_of FeatureFMI), "fmi">;
7373

7474
def HasRCPC_IMMO : Predicate<"Subtarget->hasRCPCImm()">,
75-
AssemblerPredicate<"FeatureRCPC_IMMO", "rcpc-immo">;
75+
AssemblerPredicate<(all_of FeatureRCPC_IMMO), "rcpc-immo">;
7676

7777
def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">,
78-
AssemblerPredicate<"FeatureFPARMv8", "fp-armv8">;
78+
AssemblerPredicate<(all_of FeatureFPARMv8), "fp-armv8">;
7979
def HasNEON : Predicate<"Subtarget->hasNEON()">,
80-
AssemblerPredicate<"FeatureNEON", "neon">;
80+
AssemblerPredicate<(all_of FeatureNEON), "neon">;
8181
def HasCrypto : Predicate<"Subtarget->hasCrypto()">,
82-
AssemblerPredicate<"FeatureCrypto", "crypto">;
82+
AssemblerPredicate<(all_of FeatureCrypto), "crypto">;
8383
def HasSM4 : Predicate<"Subtarget->hasSM4()">,
84-
AssemblerPredicate<"FeatureSM4", "sm4">;
84+
AssemblerPredicate<(all_of FeatureSM4), "sm4">;
8585
def HasSHA3 : Predicate<"Subtarget->hasSHA3()">,
86-
AssemblerPredicate<"FeatureSHA3", "sha3">;
86+
AssemblerPredicate<(all_of FeatureSHA3), "sha3">;
8787
def HasSHA2 : Predicate<"Subtarget->hasSHA2()">,
88-
AssemblerPredicate<"FeatureSHA2", "sha2">;
88+
AssemblerPredicate<(all_of FeatureSHA2), "sha2">;
8989
def HasAES : Predicate<"Subtarget->hasAES()">,
90-
AssemblerPredicate<"FeatureAES", "aes">;
90+
AssemblerPredicate<(all_of FeatureAES), "aes">;
9191
def HasDotProd : Predicate<"Subtarget->hasDotProd()">,
92-
AssemblerPredicate<"FeatureDotProd", "dotprod">;
92+
AssemblerPredicate<(all_of FeatureDotProd), "dotprod">;
9393
def HasCRC : Predicate<"Subtarget->hasCRC()">,
94-
AssemblerPredicate<"FeatureCRC", "crc">;
94+
AssemblerPredicate<(all_of FeatureCRC), "crc">;
9595
def HasLSE : Predicate<"Subtarget->hasLSE()">,
96-
AssemblerPredicate<"FeatureLSE", "lse">;
96+
AssemblerPredicate<(all_of FeatureLSE), "lse">;
9797
def HasRAS : Predicate<"Subtarget->hasRAS()">,
98-
AssemblerPredicate<"FeatureRAS", "ras">;
98+
AssemblerPredicate<(all_of FeatureRAS), "ras">;
9999
def HasRDM : Predicate<"Subtarget->hasRDM()">,
100-
AssemblerPredicate<"FeatureRDM", "rdm">;
100+
AssemblerPredicate<(all_of FeatureRDM), "rdm">;
101101
def HasPerfMon : Predicate<"Subtarget->hasPerfMon()">;
102102
def HasFullFP16 : Predicate<"Subtarget->hasFullFP16()">,
103-
AssemblerPredicate<"FeatureFullFP16", "fullfp16">;
103+
AssemblerPredicate<(all_of FeatureFullFP16), "fullfp16">;
104104
def HasFP16FML : Predicate<"Subtarget->hasFP16FML()">,
105-
AssemblerPredicate<"FeatureFP16FML", "fp16fml">;
105+
AssemblerPredicate<(all_of FeatureFP16FML), "fp16fml">;
106106
def HasSPE : Predicate<"Subtarget->hasSPE()">,
107-
AssemblerPredicate<"FeatureSPE", "spe">;
107+
AssemblerPredicate<(all_of FeatureSPE), "spe">;
108108
def HasFuseAES : Predicate<"Subtarget->hasFuseAES()">,
109-
AssemblerPredicate<"FeatureFuseAES",
109+
AssemblerPredicate<(all_of FeatureFuseAES),
110110
"fuse-aes">;
111111
def HasSVE : Predicate<"Subtarget->hasSVE()">,
112-
AssemblerPredicate<"FeatureSVE", "sve">;
112+
AssemblerPredicate<(all_of FeatureSVE), "sve">;
113113
def HasSVE2 : Predicate<"Subtarget->hasSVE2()">,
114-
AssemblerPredicate<"FeatureSVE2", "sve2">;
114+
AssemblerPredicate<(all_of FeatureSVE2), "sve2">;
115115
def HasSVE2AES : Predicate<"Subtarget->hasSVE2AES()">,
116-
AssemblerPredicate<"FeatureSVE2AES", "sve2-aes">;
116+
AssemblerPredicate<(all_of FeatureSVE2AES), "sve2-aes">;
117117
def HasSVE2SM4 : Predicate<"Subtarget->hasSVE2SM4()">,
118-
AssemblerPredicate<"FeatureSVE2SM4", "sve2-sm4">;
118+
AssemblerPredicate<(all_of FeatureSVE2SM4), "sve2-sm4">;
119119
def HasSVE2SHA3 : Predicate<"Subtarget->hasSVE2SHA3()">,
120-
AssemblerPredicate<"FeatureSVE2SHA3", "sve2-sha3">;
120+
AssemblerPredicate<(all_of FeatureSVE2SHA3), "sve2-sha3">;
121121
def HasSVE2BitPerm : Predicate<"Subtarget->hasSVE2BitPerm()">,
122-
AssemblerPredicate<"FeatureSVE2BitPerm", "sve2-bitperm">;
122+
AssemblerPredicate<(all_of FeatureSVE2BitPerm), "sve2-bitperm">;
123123
def HasRCPC : Predicate<"Subtarget->hasRCPC()">,
124-
AssemblerPredicate<"FeatureRCPC", "rcpc">;
124+
AssemblerPredicate<(all_of FeatureRCPC), "rcpc">;
125125
def HasAltNZCV : Predicate<"Subtarget->hasAlternativeNZCV()">,
126-
AssemblerPredicate<"FeatureAltFPCmp", "altnzcv">;
126+
AssemblerPredicate<(all_of FeatureAltFPCmp), "altnzcv">;
127127
def HasFRInt3264 : Predicate<"Subtarget->hasFRInt3264()">,
128-
AssemblerPredicate<"FeatureFRInt3264", "frint3264">;
128+
AssemblerPredicate<(all_of FeatureFRInt3264), "frint3264">;
129129
def HasSB : Predicate<"Subtarget->hasSB()">,
130-
AssemblerPredicate<"FeatureSB", "sb">;
130+
AssemblerPredicate<(all_of FeatureSB), "sb">;
131131
def HasPredRes : Predicate<"Subtarget->hasPredRes()">,
132-
AssemblerPredicate<"FeaturePredRes", "predres">;
132+
AssemblerPredicate<(all_of FeaturePredRes), "predres">;
133133
def HasCCDP : Predicate<"Subtarget->hasCCDP()">,
134-
AssemblerPredicate<"FeatureCacheDeepPersist", "ccdp">;
134+
AssemblerPredicate<(all_of FeatureCacheDeepPersist), "ccdp">;
135135
def HasBTI : Predicate<"Subtarget->hasBTI()">,
136-
AssemblerPredicate<"FeatureBranchTargetId", "bti">;
136+
AssemblerPredicate<(all_of FeatureBranchTargetId), "bti">;
137137
def HasMTE : Predicate<"Subtarget->hasMTE()">,
138-
AssemblerPredicate<"FeatureMTE", "mte">;
138+
AssemblerPredicate<(all_of FeatureMTE), "mte">;
139139
def HasTME : Predicate<"Subtarget->hasTME()">,
140-
AssemblerPredicate<"FeatureTME", "tme">;
140+
AssemblerPredicate<(all_of FeatureTME), "tme">;
141141
def HasETE : Predicate<"Subtarget->hasETE()">,
142-
AssemblerPredicate<"FeatureETE", "ete">;
142+
AssemblerPredicate<(all_of FeatureETE), "ete">;
143143
def HasTRBE : Predicate<"Subtarget->hasTRBE()">,
144-
AssemblerPredicate<"FeatureTRBE", "trbe">;
144+
AssemblerPredicate<(all_of FeatureTRBE), "trbe">;
145145
def IsLE : Predicate<"Subtarget->isLittleEndian()">;
146146
def IsBE : Predicate<"!Subtarget->isLittleEndian()">;
147147
def IsWindows : Predicate<"Subtarget->isTargetWindows()">;
148148
def UseAlternateSExtLoadCVTF32
149149
: Predicate<"Subtarget->useAlternateSExtLoadCVTF32Pattern()">;
150150

151151
def UseNegativeImmediates
152-
: Predicate<"false">, AssemblerPredicate<"!FeatureNoNegativeImmediates",
152+
: Predicate<"false">, AssemblerPredicate<(all_of (not FeatureNoNegativeImmediates)),
153153
"NegativeImmediates">;
154154

155155
def AArch64LocalRecover : SDNode<"ISD::LOCAL_RECOVER",

llvm/lib/Target/AArch64/AArch64SystemOperands.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ include "llvm/TableGen/SearchableTable.td"
1818
//===----------------------------------------------------------------------===//
1919

2020
def HasCCPP : Predicate<"Subtarget->hasCCPP()">,
21-
AssemblerPredicate<"FeatureCCPP", "ccpp">;
21+
AssemblerPredicate<(all_of FeatureCCPP), "ccpp">;
2222

2323
def HasPAN : Predicate<"Subtarget->hasPAN()">,
24-
AssemblerPredicate<"FeaturePAN",
24+
AssemblerPredicate<(all_of FeaturePAN),
2525
"ARM v8.1 Privileged Access-Never extension">;
2626

2727
def HasPsUAO : Predicate<"Subtarget->hasPsUAO()">,
28-
AssemblerPredicate<"FeaturePsUAO",
28+
AssemblerPredicate<(all_of FeaturePsUAO),
2929
"ARM v8.2 UAO PState extension (psuao)">;
3030

3131
def HasPAN_RWV : Predicate<"Subtarget->hasPAN_RWV()">,
32-
AssemblerPredicate<"FeaturePAN_RWV",
32+
AssemblerPredicate<(all_of FeaturePAN_RWV),
3333
"ARM v8.2 PAN AT S1E1R and AT S1E1W Variation">;
3434

3535
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)