@@ -441,10 +441,6 @@ class LowerTypeTestsModule {
441441 // Cache variable used by hasBranchTargetEnforcement().
442442 int HasBranchTargetEnforcement = -1 ;
443443
444- // The jump table type we ended up deciding on. (Usually the same as
445- // Arch, except that 'arm' and 'thumb' are often interchangeable.)
446- Triple::ArchType JumpTableArch = Triple::UnknownArch;
447-
448444 IntegerType *Int1Ty = Type::getInt1Ty(M.getContext());
449445 IntegerType *Int8Ty = Type::getInt8Ty(M.getContext());
450446 PointerType *PtrTy = PointerType::getUnqual(M.getContext());
@@ -525,11 +521,8 @@ class LowerTypeTestsModule {
525521 Triple::ArchType
526522 selectJumpTableArmEncoding (ArrayRef<GlobalTypeMember *> Functions);
527523 bool hasBranchTargetEnforcement ();
528- unsigned getJumpTableEntrySize ();
529- Type *getJumpTableEntryType ();
530- void createJumpTableEntry (raw_ostream &AsmOS, raw_ostream &ConstraintOS,
531- Triple::ArchType JumpTableArch,
532- SmallVectorImpl<Value *> &AsmArgs, Function *Dest);
524+ unsigned getJumpTableEntrySize (Triple::ArchType JumpTableArch);
525+ InlineAsm *createJumpTableEntryAsm (Triple::ArchType JumpTableArch);
533526 void verifyTypeMDNode (GlobalObject *GO, MDNode *Type);
534527 void buildBitSetsFromFunctions (ArrayRef<Metadata *> TypeIds,
535528 ArrayRef<GlobalTypeMember *> Functions);
@@ -548,7 +541,8 @@ class LowerTypeTestsModule {
548541 void findGlobalVariableUsersOf (Constant *C,
549542 SmallSetVector<GlobalVariable *, 8 > &Out);
550543
551- void createJumpTable (Function *F, ArrayRef<GlobalTypeMember *> Functions);
544+ void createJumpTable (Function *F, ArrayRef<GlobalTypeMember *> Functions,
545+ Triple::ArchType JumpTableArch);
552546
553547 // / replaceCfiUses - Go through the uses list for this definition
554548 // / and make each use point to "V" instead of "this" when the use is outside
@@ -1245,7 +1239,8 @@ bool LowerTypeTestsModule::hasBranchTargetEnforcement() {
12451239 return HasBranchTargetEnforcement;
12461240}
12471241
1248- unsigned LowerTypeTestsModule::getJumpTableEntrySize () {
1242+ unsigned
1243+ LowerTypeTestsModule::getJumpTableEntrySize (Triple::ArchType JumpTableArch) {
12491244 switch (JumpTableArch) {
12501245 case Triple::x86:
12511246 case Triple::x86_64:
@@ -1278,33 +1273,32 @@ unsigned LowerTypeTestsModule::getJumpTableEntrySize() {
12781273 }
12791274}
12801275
1281- // Create a jump table entry for the target. This consists of an instruction
1282- // sequence containing a relative branch to Dest. Appends inline asm text,
1283- // constraints and arguments to AsmOS, ConstraintOS and AsmArgs.
1284- void LowerTypeTestsModule::createJumpTableEntry (
1285- raw_ostream &AsmOS, raw_ostream &ConstraintOS,
1286- Triple::ArchType JumpTableArch, SmallVectorImpl<Value *> &AsmArgs,
1287- Function *Dest) {
1288- unsigned ArgIndex = AsmArgs.size ();
1276+ // Create an inline asm constant representing a jump table entry for the target.
1277+ // This consists of an instruction sequence containing a relative branch to
1278+ // Dest.
1279+ InlineAsm *
1280+ LowerTypeTestsModule::createJumpTableEntryAsm (Triple::ArchType JumpTableArch) {
1281+ std::string Asm;
1282+ raw_string_ostream AsmOS (Asm);
12891283
12901284 if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64) {
12911285 bool Endbr = false ;
12921286 if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1293- Dest-> getParent ()-> getModuleFlag (" cf-protection-branch" )))
1287+ M. getModuleFlag (" cf-protection-branch" )))
12941288 Endbr = !MD->isZero ();
12951289 if (Endbr)
12961290 AsmOS << (JumpTableArch == Triple::x86 ? " endbr32\n " : " endbr64\n " );
1297- AsmOS << " jmp ${" << ArgIndex << " :c}@plt\n " ;
1291+ AsmOS << " jmp ${0 :c}@plt\n " ;
12981292 if (Endbr)
12991293 AsmOS << " .balign 16, 0xcc\n " ;
13001294 else
13011295 AsmOS << " int3\n int3\n int3\n " ;
13021296 } else if (JumpTableArch == Triple::arm) {
1303- AsmOS << " b $" << ArgIndex << " \n " ;
1297+ AsmOS << " b $0 \n " ;
13041298 } else if (JumpTableArch == Triple::aarch64) {
13051299 if (hasBranchTargetEnforcement ())
13061300 AsmOS << " bti c\n " ;
1307- AsmOS << " b $" << ArgIndex << " \n " ;
1301+ AsmOS << " b $0 \n " ;
13081302 } else if (JumpTableArch == Triple::thumb) {
13091303 if (!CanUseThumbBWJumpTable) {
13101304 // In Armv6-M, this sequence will generate a branch without corrupting
@@ -1328,28 +1322,26 @@ void LowerTypeTestsModule::createJumpTableEntry(
13281322 << " str r0, [sp, #4]\n "
13291323 << " pop {r0,pc}\n "
13301324 << " .balign 4\n "
1331- << " 1: .word $" << ArgIndex << " - (0b + 4)\n " ;
1325+ << " 1: .word $0 - (0b + 4)\n " ;
13321326 } else {
13331327 if (hasBranchTargetEnforcement ())
13341328 AsmOS << " bti\n " ;
1335- AsmOS << " b.w $" << ArgIndex << " \n " ;
1329+ AsmOS << " b.w $0 \n " ;
13361330 }
13371331 } else if (JumpTableArch == Triple::riscv32 ||
13381332 JumpTableArch == Triple::riscv64) {
1339- AsmOS << " tail $" << ArgIndex << " @plt\n " ;
1333+ AsmOS << " tail $0 @plt\n " ;
13401334 } else if (JumpTableArch == Triple::loongarch64) {
1341- AsmOS << " pcalau12i $$t0, %pc_hi20($" << ArgIndex << " )\n "
1342- << " jirl $$r0, $$t0, %pc_lo12($" << ArgIndex << " )\n " ;
1335+ AsmOS << " pcalau12i $$t0, %pc_hi20($0 )\n "
1336+ << " jirl $$r0, $$t0, %pc_lo12($0 )\n " ;
13431337 } else {
13441338 report_fatal_error (" Unsupported architecture for jump tables" );
13451339 }
13461340
1347- ConstraintOS << (ArgIndex > 0 ? " ,s" : " s" );
1348- AsmArgs.push_back (Dest);
1349- }
1350-
1351- Type *LowerTypeTestsModule::getJumpTableEntryType () {
1352- return ArrayType::get (Int8Ty, getJumpTableEntrySize ());
1341+ return InlineAsm::get (
1342+ FunctionType::get (Type::getVoidTy (M.getContext ()), PtrTy, false ),
1343+ AsmOS.str (), " s" ,
1344+ /* hasSideEffects=*/ true );
13531345}
13541346
13551347// / Given a disjoint set of type identifiers and functions, build the bit sets
@@ -1498,12 +1490,18 @@ Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
14981490}
14991491
15001492void LowerTypeTestsModule::createJumpTable (
1501- Function *F, ArrayRef<GlobalTypeMember *> Functions) {
1493+ Function *F, ArrayRef<GlobalTypeMember *> Functions,
1494+ Triple::ArchType JumpTableArch) {
15021495 std::string AsmStr, ConstraintStr;
15031496 raw_string_ostream AsmOS (AsmStr), ConstraintOS (ConstraintStr);
15041497 SmallVector<Value *, 16 > AsmArgs;
15051498 AsmArgs.reserve (Functions.size () * 2 );
15061499
1500+ BasicBlock *BB = BasicBlock::Create (M.getContext (), " entry" , F);
1501+ IRBuilder<> IRB (BB);
1502+
1503+ InlineAsm *JumpTableAsm = createJumpTableEntryAsm (JumpTableArch);
1504+
15071505 // Check if all entries have the NoUnwind attribute.
15081506 // If all entries have it, we can safely mark the
15091507 // cfi.jumptable as NoUnwind, otherwise, direct calls
@@ -1514,12 +1512,12 @@ void LowerTypeTestsModule::createJumpTable(
15141512 ->hasFnAttribute (llvm::Attribute::NoUnwind)) {
15151513 areAllEntriesNounwind = false ;
15161514 }
1517- createJumpTableEntry (AsmOS, ConstraintOS, JumpTableArch, AsmArgs,
1518- cast<Function>(GTM->getGlobal ()));
1515+ IRB.CreateCall (JumpTableAsm, GTM->getGlobal ());
15191516 }
1517+ IRB.CreateUnreachable ();
15201518
15211519 // Align the whole table by entry size.
1522- F->setAlignment (Align (getJumpTableEntrySize ()));
1520+ F->setAlignment (Align (getJumpTableEntrySize (JumpTableArch )));
15231521 // Skip prologue.
15241522 // Disabled on win32 due to https://llvm.org/bugs/show_bug.cgi?id=28641#c3.
15251523 // Luckily, this function does not get any prologue even without the
@@ -1568,21 +1566,6 @@ void LowerTypeTestsModule::createJumpTable(
15681566
15691567 // Make sure we do not inline any calls to the cfi.jumptable.
15701568 F->addFnAttr (Attribute::NoInline);
1571-
1572- BasicBlock *BB = BasicBlock::Create (M.getContext (), " entry" , F);
1573- IRBuilder<> IRB (BB);
1574-
1575- SmallVector<Type *, 16 > ArgTypes;
1576- ArgTypes.reserve (AsmArgs.size ());
1577- for (const auto &Arg : AsmArgs)
1578- ArgTypes.push_back (Arg->getType ());
1579- InlineAsm *JumpTableAsm =
1580- InlineAsm::get (FunctionType::get (IRB.getVoidTy (), ArgTypes, false ),
1581- AsmOS.str (), ConstraintOS.str (),
1582- /* hasSideEffects=*/ true );
1583-
1584- IRB.CreateCall (JumpTableAsm, AsmArgs);
1585- IRB.CreateUnreachable ();
15861569}
15871570
15881571// / Given a disjoint set of type identifiers and functions, build a jump table
@@ -1669,11 +1652,11 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
16691652
16701653 // Decide on the jump table encoding, so that we know how big the
16711654 // entries will be.
1672- JumpTableArch = selectJumpTableArmEncoding (Functions);
1655+ Triple::ArchType JumpTableArch = selectJumpTableArmEncoding (Functions);
16731656
16741657 // Build a simple layout based on the regular layout of jump tables.
16751658 DenseMap<GlobalTypeMember *, uint64_t > GlobalLayout;
1676- unsigned EntrySize = getJumpTableEntrySize ();
1659+ unsigned EntrySize = getJumpTableEntrySize (JumpTableArch );
16771660 for (unsigned I = 0 ; I != Functions.size (); ++I)
16781661 GlobalLayout[Functions[I]] = I * EntrySize;
16791662
@@ -1684,7 +1667,7 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
16841667 M.getDataLayout ().getProgramAddressSpace (),
16851668 " .cfi.jumptable" , &M);
16861669 ArrayType *JumpTableType =
1687- ArrayType::get (getJumpTableEntryType ( ), Functions.size ());
1670+ ArrayType::get (ArrayType::get (Int8Ty, EntrySize ), Functions.size ());
16881671 auto JumpTable = ConstantExpr::getPointerCast (
16891672 JumpTableFn, PointerType::getUnqual (M.getContext ()));
16901673
@@ -1742,7 +1725,7 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
17421725 }
17431726 }
17441727
1745- createJumpTable (JumpTableFn, Functions);
1728+ createJumpTable (JumpTableFn, Functions, JumpTableArch );
17461729}
17471730
17481731// / Assign a dummy layout using an incrementing counter, tag each function
0 commit comments