Skip to content

Commit e50372c

Browse files
authored
[TableGen] Emit integers in GlobalISelMatchTable as unsigned (#153391)
The numbers are stored in an `uint8_t` array, either directly or via `GIMT_Encode2/4/8` macros (see `getEncodedEmitStr` and `emitEncodingMacrosDef`). Passing negative numbers only adds confusion and results in a warning for the `INT64_MIN` value (C++ parses `-9223372036854775808` as two tokens: a unary minus and an unsigned integer, triggered in #151687). BTW, parenthesize parameters in `GIMT_Encode2/4/8` macros and avoid unnecessary casts.
1 parent 0a9ca5d commit e50372c

File tree

5 files changed

+64
-33
lines changed

5 files changed

+64
-33
lines changed

llvm/test/TableGen/GlobalISelCombinerEmitter/match-table-typeof.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ def Test0 : GICombineRule<
2020
// CHECK-NEXT: GIM_CheckSimplePredicate, GIMT_Encode2(GICXXPred_Simple_IsRule0Enabled),
2121
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_MUL),
2222
// CHECK-NEXT: // MIs[0] dst
23-
// CHECK-NEXT: GIM_RecordRegType, /*MI*/0, /*Op*/0, /*TempTypeIdx*/uint8_t(-1),
23+
// CHECK-NEXT: GIM_RecordRegType, /*MI*/0, /*Op*/0, /*TempTypeIdx*/255,
2424
// CHECK-NEXT: // MIs[0] src
25-
// CHECK-NEXT: GIM_RecordRegType, /*MI*/0, /*Op*/1, /*TempTypeIdx*/uint8_t(-2),
25+
// CHECK-NEXT: GIM_RecordRegType, /*MI*/0, /*Op*/1, /*TempTypeIdx*/254,
2626
// CHECK-NEXT: // MIs[0] Operand 2
27-
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-1),
28-
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/1, /*TypeID*/uint8_t(-2),
27+
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 255,
28+
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/1, /*TypeID*/254,
2929
// CHECK-NEXT: GIR_BuildConstant, /*TempRegID*/1, /*Val*/GIMT_Encode8(0),
30-
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/uint8_t(-1),
30+
// CHECK-NEXT: GIR_MakeTempReg, /*TempRegID*/0, /*TypeID*/255,
3131
// CHECK-NEXT: // Combiner Rule #0: Test0
3232
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(TargetOpcode::G_CONSTANT),
3333
// CHECK-NEXT: GIR_AddTempRegister, /*InsnID*/0, /*TempRegID*/0, /*TempRegFlags*/GIMT_Encode2(RegState::Define),
34-
// CHECK-NEXT: GIR_AddCImm, /*InsnID*/0, /*Type*/uint8_t(-2), /*Imm*/GIMT_Encode8(42),
34+
// CHECK-NEXT: GIR_AddCImm, /*InsnID*/0, /*Type*/254, /*Imm*/GIMT_Encode8(42),
3535
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/1, /*Opcode*/GIMT_Encode2(TargetOpcode::G_SUB),
3636
// CHECK-NEXT: GIR_Copy, /*NewInsnID*/1, /*OldInsnID*/0, /*OpIdx*/0, // dst
3737
// CHECK-NEXT: GIR_AddSimpleTempRegister, /*InsnID*/1, /*TempRegID*/1,

llvm/test/TableGen/GlobalISelCombinerEmitter/match-table.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ def MyCombiner: GICombiner<"GenMyCombiner", [
181181
// CHECK-NEXT: GIM_RecordInsnIgnoreCopies, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
182182
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, GIMT_Encode2(TargetOpcode::G_CONSTANT),
183183
// CHECK-NEXT: // MIs[1] z
184-
// CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/1, /*Op*/1, GIMT_Encode8(-42),
184+
// CHECK-NEXT: GIM_CheckLiteralInt, /*MI*/1, /*Op*/1, GIMT_Encode8(18446744073709551574),
185185
// CHECK-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 43,
186186
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*NumInsns*/1,
187187
// CHECK-NEXT: // Combiner Rule #5: InOutInstTest1

llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -617,11 +617,11 @@ def MOV : I<(outs GPR32:$dst), (ins GPR32:$src1),
617617
// R02N-NEXT: // MIs[0] Operand 2
618618
// R02N-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
619619
//
620-
// R02C-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-2)
620+
// R02C-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 254,
621621
// R02C-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -2:{ *:[i32] }) => (XORI:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
622622
// R02C-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORI),
623623
// R02C-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
624-
// R02C-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/uint8_t(-1),
624+
// R02C-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,
625625
// R02C-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1
626626
// R02C-NEXT: GIR_RootConstrainSelectedInstOperands,
627627
// R02C-NEXT: // GIR_Coverage, 2,
@@ -648,7 +648,7 @@ def XORI : I<(outs GPR32:$dst), (ins m1:$src2, GPR32:$src1),
648648
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
649649
// NOOPT-NEXT: // MIs[0] Operand 2
650650
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
651-
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-3)
651+
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 253,
652652
// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -3:{ *:[i32] }) => (XOR:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
653653
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XOR),
654654
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
@@ -676,11 +676,11 @@ def XOR : I<(outs GPR32:$dst), (ins Z:$src2, GPR32:$src1),
676676
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
677677
// NOOPT-NEXT: // MIs[0] Operand 2
678678
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
679-
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-4)
679+
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 252,
680680
// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -4:{ *:[i32] }) => (XORlike:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
681681
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORlike),
682682
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
683-
// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/uint8_t(-1),
683+
// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,
684684
// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),
685685
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1
686686
// NOOPT-NEXT: GIR_RootConstrainSelectedInstOperands,
@@ -705,11 +705,11 @@ def XORlike : I<(outs GPR32:$dst), (ins m1Z:$src2, GPR32:$src1),
705705
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
706706
// NOOPT-NEXT: // MIs[0] Operand 2
707707
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
708-
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-5),
708+
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 251,
709709
// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -5:{ *:[i32] }) => (XORManyDefaults:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
710710
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORManyDefaults),
711711
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
712-
// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/uint8_t(-1),
712+
// NOOPT-NEXT: GIR_AddImm8, /*InsnID*/0, /*Imm*/255,
713713
// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),
714714
// NOOPT-NEXT: GIR_AddRegister, /*InsnID*/0, GIMT_Encode2(MyTarget::R0),
715715
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // src1
@@ -735,7 +735,7 @@ def XORManyDefaults : I<(outs GPR32:$dst), (ins m1Z:$src3, Z:$src2, GPR32:$src1)
735735
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
736736
// NOOPT-NEXT: // MIs[0] Operand 2
737737
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
738-
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-6)
738+
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 250,
739739
// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$src1, -6:{ *:[i32] }) => (XORIb:{ *:[i32] } GPR32:{ *:[i32] }:$src1)
740740
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::XORIb),
741741
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
@@ -766,7 +766,7 @@ def XORIb : I<(outs GPR32:$dst), (ins mb:$src2, GPR32:$src1),
766766
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
767767
// NOOPT-NEXT: // MIs[0] Operand 2
768768
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s32,
769-
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, uint8_t(-1),
769+
// NOOPT-NEXT: GIM_CheckConstantInt8, /*MI*/0, /*Op*/2, 255,
770770
// NOOPT-NEXT: // (xor:{ *:[i32] } GPR32:{ *:[i32] }:$Wm, -1:{ *:[i32] }) => (ORN:{ *:[i32] } R0:{ *:[i32] }, GPR32:{ *:[i32] }:$Wm)
771771
// NOOPT-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ORN),
772772
// NOOPT-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../../include -I %p/../Common %s | FileCheck %s
2+
3+
include "llvm/Target/Target.td"
4+
include "GlobalISelEmitterCommon.td"
5+
6+
def GPR : RegisterClass<"MyTarget", [i64], 64, (add R0)>;
7+
def ANDI : I<(outs GPR:$dst), (ins GPR:$src1, i64imm:$src2), []>;
8+
9+
// CHECK-LABEL: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4(59), // Rule ID 0 //
10+
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
11+
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_AND),
12+
// CHECK-NEXT: // MIs[0] DstI[dst]
13+
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s64,
14+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
15+
// CHECK-NEXT: // MIs[0] rs1
16+
// CHECK-NEXT: GIM_RootCheckType, /*Op*/1, /*Type*/GILLT_s64,
17+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
18+
// CHECK-NEXT: // MIs[0] Operand 2
19+
// CHECK-NEXT: GIM_RootCheckType, /*Op*/2, /*Type*/GILLT_s64,
20+
// CHECK-NEXT: GIM_CheckConstantInt, /*MI*/0, /*Op*/2, GIMT_Encode8(9223372036854775808),
21+
// CHECK-NEXT: // (and:{ *:[i64] } GPR:{ *:[i64] }:$rs1, -9223372036854775808:{ *:[i64] }) => (ANDI:{ *:[i64] } GPR:{ *:[i64] }:$rs1, -9223372036854775808:{ *:[i64] })
22+
// CHECK-NEXT: GIR_BuildRootMI, /*Opcode*/GIMT_Encode2(MyTarget::ANDI),
23+
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/0, // DstI[dst]
24+
// CHECK-NEXT: GIR_RootToRootCopy, /*OpIdx*/1, // rs1
25+
// CHECK-NEXT: GIR_AddImm, /*InsnID*/0, /*Imm*/GIMT_Encode8(9223372036854775808),
26+
// CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
27+
// CHECK-NEXT: // GIR_Coverage, 0,
28+
// CHECK-NEXT: GIR_EraseRootFromParent_Done,
29+
def : Pat<(and GPR:$rs1, 0x8000000000000000),
30+
(ANDI GPR:$rs1, 0x8000000000000000)>;

llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,26 @@ constexpr StringLiteral EncodeMacroName = "GIMT_Encode";
5353
void emitEncodingMacrosDef(raw_ostream &OS) {
5454
OS << "#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__\n"
5555
<< "#define " << EncodeMacroName << "2(Val)"
56-
<< " uint8_t(Val), uint8_t((uint16_t)Val >> 8)\n"
56+
<< " uint8_t(Val), uint8_t((Val) >> 8)\n"
5757
<< "#define " << EncodeMacroName << "4(Val)"
58-
<< " uint8_t(Val), uint8_t((uint32_t)Val >> 8), "
59-
"uint8_t((uint32_t)Val >> 16), uint8_t((uint32_t)Val >> 24)\n"
58+
<< " uint8_t(Val), uint8_t((Val) >> 8), "
59+
"uint8_t((Val) >> 16), uint8_t((Val) >> 24)\n"
6060
<< "#define " << EncodeMacroName << "8(Val)"
61-
<< " uint8_t(Val), uint8_t((uint64_t)Val >> 8), "
62-
"uint8_t((uint64_t)Val >> 16), uint8_t((uint64_t)Val >> 24), "
63-
"uint8_t((uint64_t)Val >> 32), uint8_t((uint64_t)Val >> 40), "
64-
"uint8_t((uint64_t)Val >> 48), uint8_t((uint64_t)Val >> 56)\n"
61+
<< " uint8_t(Val), uint8_t((Val) >> 8), "
62+
"uint8_t((Val) >> 16), uint8_t((Val) >> 24), "
63+
"uint8_t(uint64_t(Val) >> 32), uint8_t(uint64_t(Val) >> 40), "
64+
"uint8_t(uint64_t(Val) >> 48), uint8_t(uint64_t(Val) >> 56)\n"
6565
<< "#else\n"
6666
<< "#define " << EncodeMacroName << "2(Val)"
67-
<< " uint8_t((uint16_t)Val >> 8), uint8_t(Val)\n"
67+
<< " uint8_t((Val) >> 8), uint8_t(Val)\n"
6868
<< "#define " << EncodeMacroName << "4(Val)"
69-
<< " uint8_t((uint32_t)Val >> 24), uint8_t((uint32_t)Val >> 16), "
70-
"uint8_t((uint32_t)Val >> 8), uint8_t(Val)\n"
69+
<< " uint8_t((Val) >> 24), uint8_t((Val) >> 16), "
70+
"uint8_t((Val) >> 8), uint8_t(Val)\n"
7171
<< "#define " << EncodeMacroName << "8(Val)"
72-
<< " uint8_t((uint64_t)Val >> 56), uint8_t((uint64_t)Val >> 48), "
73-
"uint8_t((uint64_t)Val >> 40), uint8_t((uint64_t)Val >> 32), "
74-
"uint8_t((uint64_t)Val >> 24), uint8_t((uint64_t)Val >> 16), "
75-
"uint8_t((uint64_t)Val >> 8), uint8_t(Val)\n"
72+
<< " uint8_t(uint64_t(Val) >> 56), uint8_t(uint64_t(Val) >> 48), "
73+
"uint8_t(uint64_t(Val) >> 40), uint8_t(uint64_t(Val) >> 32), "
74+
"uint8_t((Val) >> 24), uint8_t((Val) >> 16), "
75+
"uint8_t((Val) >> 8), uint8_t(Val)\n"
7676
<< "#endif\n";
7777
}
7878

@@ -237,9 +237,10 @@ MatchTableRecord MatchTable::NamedValue(unsigned NumBytes, StringRef Namespace,
237237

238238
MatchTableRecord MatchTable::IntValue(unsigned NumBytes, int64_t IntValue) {
239239
assert(isUIntN(NumBytes * 8, IntValue) || isIntN(NumBytes * 8, IntValue));
240-
auto Str = llvm::to_string(IntValue);
241-
if (NumBytes == 1 && IntValue < 0)
242-
Str = "uint8_t(" + Str + ")";
240+
uint64_t UIntValue = IntValue;
241+
if (NumBytes < 8)
242+
UIntValue &= (UINT64_C(1) << NumBytes * 8) - 1;
243+
std::string Str = llvm::to_string(UIntValue);
243244
// TODO: Could optimize this directly to save the compiler some work when
244245
// building the file
245246
return MatchTableRecord(std::nullopt, Str, NumBytes,

0 commit comments

Comments
 (0)