Skip to content

Commit dd88f40

Browse files
committed
[AArch64] Make getInstSizeInBytes() use instruction size from InstrInfo.td
Currently, AArch64InstrInfo::getInstSizeInBytes() uses hard-coded instruction size for some pseudo-instructions, while this information should ideally be found in AArch64InstrInfo.td file (which can be accessed via MCInstrDesc). Hence, the .td file should be updated and no hard-coded instruction sizes should be used by getInstSizeInBytes() anymore. Differential Revision: https://reviews.llvm.org/D117970
1 parent b00bce2 commit dd88f40

File tree

3 files changed

+128
-31
lines changed

3 files changed

+128
-31
lines changed

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,18 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
9393
// before the assembly printer.
9494
unsigned NumBytes = 0;
9595
const MCInstrDesc &Desc = MI.getDesc();
96+
97+
// Size should be preferably set in
98+
// llvm/lib/Target/AArch64/AArch64InstrInfo.td (default case).
99+
// Specific cases handle instructions of variable sizes
96100
switch (Desc.getOpcode()) {
97101
default:
98-
// Anything not explicitly designated otherwise is a normal 4-byte insn.
102+
if (Desc.getSize())
103+
return Desc.getSize();
104+
105+
// Anything not explicitly designated otherwise (i.e. pseudo-instructions
106+
// with fixed constant size but not specified in .td file) is a normal
107+
// 4-byte insn.
99108
NumBytes = 4;
100109
break;
101110
case TargetOpcode::STACKMAP:
@@ -115,33 +124,9 @@ unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
115124
if (NumBytes == 0)
116125
NumBytes = 4;
117126
break;
118-
case AArch64::TLSDESC_CALLSEQ:
119-
// This gets lowered to an instruction sequence which takes 16 bytes
120-
NumBytes = 16;
121-
break;
122-
case AArch64::SpeculationBarrierISBDSBEndBB:
123-
// This gets lowered to 2 4-byte instructions.
124-
NumBytes = 8;
125-
break;
126-
case AArch64::SpeculationBarrierSBEndBB:
127-
// This gets lowered to 1 4-byte instructions.
128-
NumBytes = 4;
129-
break;
130-
case AArch64::JumpTableDest32:
131-
case AArch64::JumpTableDest16:
132-
case AArch64::JumpTableDest8:
133-
case AArch64::MOPSMemoryCopyPseudo:
134-
case AArch64::MOPSMemoryMovePseudo:
135-
case AArch64::MOPSMemorySetPseudo:
136-
case AArch64::MOPSMemorySetTaggingPseudo:
137-
NumBytes = 12;
138-
break;
139127
case AArch64::SPACE:
140128
NumBytes = MI.getOperand(1).getImm();
141129
break;
142-
case AArch64::StoreSwiftAsyncContext:
143-
NumBytes = 20;
144-
break;
145130
case TargetOpcode::BUNDLE:
146131
NumBytes = getInstBundleLength(MI);
147132
break;

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ def : Pat<(AArch64LOADgot texternalsym:$addr),
780780
def : Pat<(AArch64LOADgot tconstpool:$addr),
781781
(LOADgot tconstpool:$addr)>;
782782

783+
// In general these get lowered into a sequence of three 4-byte instructions.
783784
// 32-bit jump table destination is actually only 2 instructions since we can
784785
// use the table itself as a PC-relative base. But optimization occurs after
785786
// branch relaxation so be pessimistic.
@@ -815,8 +816,12 @@ let hasSideEffects = 1, isCodeGenOnly = 1 in {
815816
// SpeculationBarrierEndBB must only be used after an unconditional control
816817
// flow, i.e. after a terminator for which isBarrier is True.
817818
let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in {
819+
// This gets lowered to a pair of 4-byte instructions.
820+
let Size = 8 in
818821
def SpeculationBarrierISBDSBEndBB
819822
: Pseudo<(outs), (ins), []>, Sched<[]>;
823+
// This gets lowered to a 4-byte instruction.
824+
let Size = 4 in
820825
def SpeculationBarrierSBEndBB
821826
: Pseudo<(outs), (ins), []>, Sched<[]>;
822827
}
@@ -2356,7 +2361,8 @@ def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
23562361

23572362
// FIXME: maybe the scratch register used shouldn't be fixed to X1?
23582363
// FIXME: can "hasSideEffects be dropped?
2359-
let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1,
2364+
// This gets lowered to an instruction sequence which takes 16 bytes
2365+
let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, Size = 16,
23602366
isCodeGenOnly = 1 in
23612367
def TLSDESC_CALLSEQ
23622368
: Pseudo<(outs), (ins i64imm:$sym),
@@ -8370,6 +8376,7 @@ def AArch64mops_memset_tagging : SDNode<"AArch64ISD::MOPS_MEMSET_TAGGING", SDT_A
83708376
def AArch64mops_memcopy : SDNode<"AArch64ISD::MOPS_MEMCOPY", SDT_AArch64mops>;
83718377
def AArch64mops_memmove : SDNode<"AArch64ISD::MOPS_MEMMOVE", SDT_AArch64mops>;
83728378

8379+
// MOPS operations always contain three 4-byte instructions
83738380
let Predicates = [HasMOPS], Defs = [NZCV], Size = 12, mayStore = 1 in {
83748381
let mayLoad = 1 in {
83758382
def MOPSMemoryCopyPseudo : Pseudo<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),
@@ -8391,7 +8398,8 @@ let Predicates = [HasMOPS, HasMTE], Defs = [NZCV], Size = 12, mayLoad = 0, maySt
83918398
[], "$Rd = $Rd_wb,$Rn = $Rn_wb">, Sched<[]>;
83928399
}
83938400

8394-
let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1 in
8401+
// This gets lowered into an instruction sequence of 20 bytes
8402+
let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1, Size = 20 in
83958403
def StoreSwiftAsyncContext
83968404
: Pseudo<(outs), (ins GPR64:$ctx, GPR64sp:$base, simm9:$offset),
83978405
[]>, Sched<[]>;

llvm/unittests/Target/AArch64/InstSizes.cpp

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ void runChecks(
5252
"...\n"
5353
"---\n"
5454
"name: sizes\n"
55+
"jumpTable:\n"
56+
" kind: block-address\n"
57+
" entries:\n"
58+
" - id: 0\n"
59+
" blocks: [ '%bb.0' ]\n"
5560
"body: |\n"
5661
" bb.0:\n"
5762
+ InputMIRSnippet.str();
@@ -142,6 +147,34 @@ TEST(InstSizes, PATCHPOINT) {
142147
});
143148
}
144149

150+
TEST(InstSizes, STATEPOINT) {
151+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
152+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
153+
154+
runChecks(TM.get(), II.get(), "",
155+
" STATEPOINT 0, 0, 0, @sizes, 2, 0, 2, 0, 2, 0, 2, 1, 1, 8,"
156+
" $sp, 24, 2, 0, 2, 1, 0, 0\n",
157+
[](AArch64InstrInfo &II, MachineFunction &MF) {
158+
auto I = MF.begin()->begin();
159+
EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
160+
});
161+
}
162+
163+
TEST(InstSizes, SPACE) {
164+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
165+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
166+
167+
runChecks(TM.get(), II.get(), "",
168+
" $xzr = SPACE 1024, undef $xzr\n"
169+
" dead $xzr = SPACE 4096, $xzr\n",
170+
[](AArch64InstrInfo &II, MachineFunction &MF) {
171+
auto I = MF.begin()->begin();
172+
EXPECT_EQ(1024u, II.getInstSizeInBytes(*I));
173+
++I;
174+
EXPECT_EQ(4096u, II.getInstSizeInBytes(*I));
175+
});
176+
}
177+
145178
TEST(InstSizes, TLSDESC_CALLSEQ) {
146179
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
147180
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
@@ -156,16 +189,87 @@ TEST(InstSizes, TLSDESC_CALLSEQ) {
156189
});
157190
}
158191

159-
TEST(InstSizes, MOPSMemorySetTaggingPseudo) {
192+
TEST(InstSizes, StoreSwiftAsyncContext) {
193+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
194+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
195+
196+
runChecks(
197+
TM.get(), II.get(), "",
198+
" StoreSwiftAsyncContext $x0, $x1, 12, implicit-def $x16, "
199+
"implicit-def $x17\n",
200+
[](AArch64InstrInfo &II, MachineFunction &MF) {
201+
auto I = MF.begin()->begin();
202+
EXPECT_EQ(20u, II.getInstSizeInBytes(*I));
203+
});
204+
}
205+
206+
TEST(InstSizes, SpeculationBarrierISBDSBEndBB) {
207+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
208+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
209+
210+
runChecks(
211+
TM.get(), II.get(), "",
212+
" SpeculationBarrierISBDSBEndBB\n"
213+
" BR $x8\n",
214+
[](AArch64InstrInfo &II, MachineFunction &MF) {
215+
auto I = MF.begin()->begin();
216+
EXPECT_EQ(8u, II.getInstSizeInBytes(*I));
217+
});
218+
}
219+
220+
TEST(InstSizes, SpeculationBarrierSBEndBB) {
221+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
222+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
223+
224+
runChecks(
225+
TM.get(), II.get(), "",
226+
" SpeculationBarrierSBEndBB\n"
227+
" BR $x8\n",
228+
[](AArch64InstrInfo &II, MachineFunction &MF) {
229+
auto I = MF.begin()->begin();
230+
EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
231+
});
232+
}
233+
234+
TEST(InstSizes, JumpTable) {
160235
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
161236
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
162237

163238
runChecks(TM.get(), II.get(), "",
164-
" renamable $x0, dead renamable $x1 = MOPSMemorySetTaggingPseudo "
165-
"killed renamable $x0, killed renamable $x1, killed renamable $x2, "
166-
"implicit-def dead $nzcv\n",
239+
" $x10, $x11 = JumpTableDest32 $x9, $x8, %jump-table.0\n"
240+
" $x10, $x11 = JumpTableDest16 $x9, $x8, %jump-table.0\n"
241+
" $x10, $x11 = JumpTableDest8 $x9, $x8, %jump-table.0\n",
167242
[](AArch64InstrInfo &II, MachineFunction &MF) {
168243
auto I = MF.begin()->begin();
169244
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
245+
++I;
246+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
247+
++I;
248+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
249+
});
250+
}
251+
252+
TEST(InstSizes, MOPSMemoryPseudos) {
253+
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
254+
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
255+
256+
runChecks(TM.get(), II.get(), "",
257+
" $x0, $x1, $x2 = MOPSMemoryMovePseudo $x0, $x1, $x2, "
258+
"implicit-def $nzcv\n"
259+
" $x0, $x1 = MOPSMemorySetPseudo $x0, $x1, $x2, "
260+
"implicit-def $nzcv\n"
261+
" $x0, $x1, $x8 = MOPSMemoryCopyPseudo $x0, $x1, $x8, "
262+
"implicit-def $nzcv\n"
263+
" $x0, $x1 = MOPSMemorySetTaggingPseudo $x0, $x1, $x2, "
264+
"implicit-def $nzcv\n",
265+
[](AArch64InstrInfo &II, MachineFunction &MF) {
266+
auto I = MF.begin()->begin();
267+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
268+
++I;
269+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
270+
++I;
271+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
272+
++I;
273+
EXPECT_EQ(12u, II.getInstSizeInBytes(*I));
170274
});
171275
}

0 commit comments

Comments
 (0)