diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -93,6 +93,9 @@ // before the assembly printer. unsigned NumBytes = 0; const MCInstrDesc &Desc = MI.getDesc(); + if (Desc.getSize()) + return Desc.getSize(); + switch (Desc.getOpcode()) { default: // Anything not explicitly designated otherwise is a normal 4-byte insn. @@ -115,33 +118,9 @@ if (NumBytes == 0) NumBytes = 4; break; - case AArch64::TLSDESC_CALLSEQ: - // This gets lowered to an instruction sequence which takes 16 bytes - NumBytes = 16; - break; - case AArch64::SpeculationBarrierISBDSBEndBB: - // This gets lowered to 2 4-byte instructions. - NumBytes = 8; - break; - case AArch64::SpeculationBarrierSBEndBB: - // This gets lowered to 1 4-byte instructions. - NumBytes = 4; - break; - case AArch64::JumpTableDest32: - case AArch64::JumpTableDest16: - case AArch64::JumpTableDest8: - case AArch64::MOPSMemoryCopyPseudo: - case AArch64::MOPSMemoryMovePseudo: - case AArch64::MOPSMemorySetPseudo: - case AArch64::MOPSMemorySetTaggingPseudo: - NumBytes = 12; - break; case AArch64::SPACE: NumBytes = MI.getOperand(1).getImm(); break; - case AArch64::StoreSwiftAsyncContext: - NumBytes = 20; - break; case TargetOpcode::BUNDLE: NumBytes = getInstBundleLength(MI); break; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -815,8 +815,10 @@ // SpeculationBarrierEndBB must only be used after an unconditional control // flow, i.e. after a terminator for which isBarrier is True. let hasSideEffects = 1, isCodeGenOnly = 1, isTerminator = 1, isBarrier = 1 in { + let Size = 8 in def SpeculationBarrierISBDSBEndBB : Pseudo<(outs), (ins), []>, Sched<[]>; + let Size = 4 in def SpeculationBarrierSBEndBB : Pseudo<(outs), (ins), []>, Sched<[]>; } @@ -2356,7 +2358,7 @@ // FIXME: maybe the scratch register used shouldn't be fixed to X1? // FIXME: can "hasSideEffects be dropped? -let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, +let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, Size = 16, isCodeGenOnly = 1 in def TLSDESC_CALLSEQ : Pseudo<(outs), (ins i64imm:$sym), @@ -8392,7 +8394,7 @@ [], "$Rd = $Rd_wb,$Rn = $Rn_wb">, Sched<[]>; } -let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1 in +let Defs = [X16, X17], mayStore = 1, isCodeGenOnly = 1, Size = 20 in def StoreSwiftAsyncContext : Pseudo<(outs), (ins GPR64:$ctx, GPR64sp:$base, simm9:$offset), []>, Sched<[]>; diff --git a/llvm/unittests/Target/AArch64/InstSizes.cpp b/llvm/unittests/Target/AArch64/InstSizes.cpp --- a/llvm/unittests/Target/AArch64/InstSizes.cpp +++ b/llvm/unittests/Target/AArch64/InstSizes.cpp @@ -142,6 +142,34 @@ }); } +TEST(InstSizes, STATEPOINT) { + std::unique_ptr TM = createTargetMachine(); + std::unique_ptr II = createInstrInfo(TM.get()); + + runChecks(TM.get(), II.get(), "", + " STATEPOINT 0, 0, 0, @sizes, 2, 0, 2, 0, 2, 0, 2, 1, 1, 8," + " $sp, 24, 2, 0, 2, 1, 0, 0\n", + [](AArch64InstrInfo &II, MachineFunction &MF) { + auto I = MF.begin()->begin(); + EXPECT_EQ(4u, II.getInstSizeInBytes(*I)); + }); +} + +TEST(InstSizes, SPACE) { + std::unique_ptr TM = createTargetMachine(); + std::unique_ptr II = createInstrInfo(TM.get()); + + runChecks(TM.get(), II.get(), "", + " $xzr = SPACE 1024, undef $xzr\n" + " dead $xzr = SPACE 4096, $xzr\n", + [](AArch64InstrInfo &II, MachineFunction &MF) { + auto I = MF.begin()->begin(); + EXPECT_EQ(1024u, II.getInstSizeInBytes(*I)); + ++I; + EXPECT_EQ(4096u, II.getInstSizeInBytes(*I)); + }); +} + TEST(InstSizes, TLSDESC_CALLSEQ) { std::unique_ptr TM = createTargetMachine(); std::unique_ptr II = createInstrInfo(TM.get()); @@ -156,17 +184,31 @@ }); } -TEST(InstSizes, MOPSMemorySetTaggingPseudo) { +TEST(InstSizes, MOPSMemoryPseudos) { std::unique_ptr TM = createTargetMachine(); std::unique_ptr II = createInstrInfo(TM.get()); + auto cmpMOPSSize = [](AArch64InstrInfo &II, MachineFunction &MF) { + auto I = MF.begin()->begin(); + EXPECT_EQ(12u, II.getInstSizeInBytes(*I)); + }; + runChecks( TM.get(), II.get(), "", - " renamable $x0, dead renamable $x1 = MOPSMemorySetTaggingPseudo " - "killed renamable $x0, killed renamable $x1, killed renamable $x2, " - "implicit-def dead $nzcv\n", - [](AArch64InstrInfo &II, MachineFunction &MF) { - auto I = MF.begin()->begin(); - EXPECT_EQ(12u, II.getInstSizeInBytes(*I)); - }); + " $x0, $x1, $x2 = MOPSMemoryMovePseudo $x0, $x1, $x2, implicit-def $nzcv\n", + cmpMOPSSize); + runChecks( + TM.get(), II.get(), "", + " $x0, $x1 = MOPSMemorySetPseudo $x0, $x1, $x2, implicit-def $nzcv\n", + cmpMOPSSize); + + runChecks( + TM.get(), II.get(), "", + " $x0, $x1, $x8 = MOPSMemoryCopyPseudo $x0, $x1, $x8, implicit-def $nzcv\n", + cmpMOPSSize); + + runChecks( + TM.get(), II.get(), "", + " $x0, $x1 = MOPSMemorySetTaggingPseudo $x0, $x1, $x2, implicit-def $nzcv\n", + cmpMOPSSize); }