@@ -26265,9 +26265,6 @@ static const char *getRetpolineSymbol(const X86Subtarget &Subtarget,
26265
26265
// attempt to help out kernels and other systems where duplicating the
26266
26266
// thunks is costly.
26267
26267
switch (Reg) {
26268
- case 0:
26269
- assert(!Subtarget.is64Bit() && "R11 should always be available on x64");
26270
- return "__x86_indirect_thunk";
26271
26268
case X86::EAX:
26272
26269
assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26273
26270
return "__x86_indirect_thunk_eax";
@@ -26277,6 +26274,9 @@ static const char *getRetpolineSymbol(const X86Subtarget &Subtarget,
26277
26274
case X86::EDX:
26278
26275
assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26279
26276
return "__x86_indirect_thunk_edx";
26277
+ case X86::EDI:
26278
+ assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26279
+ return "__x86_indirect_thunk_edi";
26280
26280
case X86::R11:
26281
26281
assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!");
26282
26282
return "__x86_indirect_thunk_r11";
@@ -26286,9 +26286,6 @@ static const char *getRetpolineSymbol(const X86Subtarget &Subtarget,
26286
26286
26287
26287
// When targeting an internal COMDAT thunk use an LLVM-specific name.
26288
26288
switch (Reg) {
26289
- case 0:
26290
- assert(!Subtarget.is64Bit() && "R11 should always be available on x64");
26291
- return "__llvm_retpoline_push";
26292
26289
case X86::EAX:
26293
26290
assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26294
26291
return "__llvm_retpoline_eax";
@@ -26298,6 +26295,9 @@ static const char *getRetpolineSymbol(const X86Subtarget &Subtarget,
26298
26295
case X86::EDX:
26299
26296
assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26300
26297
return "__llvm_retpoline_edx";
26298
+ case X86::EDI:
26299
+ assert(!Subtarget.is64Bit() && "Should not be using a 32-bit thunk!");
26300
+ return "__llvm_retpoline_edi";
26301
26301
case X86::R11:
26302
26302
assert(Subtarget.is64Bit() && "Should not be using a 64-bit thunk!");
26303
26303
return "__llvm_retpoline_r11";
@@ -26319,15 +26319,13 @@ X86TargetLowering::EmitLoweredRetpoline(MachineInstr &MI,
26319
26319
// just use R11, but we scan for uses anyway to ensure we don't generate
26320
26320
// incorrect code. On 32-bit, we use one of EAX, ECX, or EDX that isn't
26321
26321
// already a register use operand to the call to hold the callee. If none
26322
- // are available, push the callee instead. This is less efficient, but is
26323
- // necessary for functions using 3 regparms. Such function calls are
26324
- // (currently) not eligible for tail call optimization, because there is no
26325
- // scratch register available to hold the address of the callee.
26322
+ // are available, use EDI instead. EDI is chosen because EBX is the PIC base
26323
+ // register and ESI is the base pointer to realigned stack frames with VLAs.
26326
26324
SmallVector<unsigned, 3> AvailableRegs;
26327
26325
if (Subtarget.is64Bit())
26328
26326
AvailableRegs.push_back(X86::R11);
26329
26327
else
26330
- AvailableRegs.append({X86::EAX, X86::ECX, X86::EDX});
26328
+ AvailableRegs.append({X86::EAX, X86::ECX, X86::EDX, X86::EDI });
26331
26329
26332
26330
// Zero out any registers that are already used.
26333
26331
for (const auto &MO : MI.operands()) {
@@ -26345,30 +26343,18 @@ X86TargetLowering::EmitLoweredRetpoline(MachineInstr &MI,
26345
26343
break;
26346
26344
}
26347
26345
}
26346
+ if (!AvailableReg)
26347
+ report_fatal_error("calling convention incompatible with retpoline, no "
26348
+ "available registers");
26348
26349
26349
26350
const char *Symbol = getRetpolineSymbol(Subtarget, AvailableReg);
26350
26351
26351
- if (AvailableReg == 0) {
26352
- // No register available. Use PUSH. This must not be a tailcall, and this
26353
- // must not be x64.
26354
- if (Subtarget.is64Bit())
26355
- report_fatal_error(
26356
- "Cannot make an indirect call on x86-64 using both retpoline and a "
26357
- "calling convention that preservers r11");
26358
- if (Opc != X86::CALLpcrel32)
26359
- report_fatal_error("Cannot make an indirect tail call on x86 using "
26360
- "retpoline without a preserved register");
26361
- BuildMI(*BB, MI, DL, TII->get(X86::PUSH32r)).addReg(CalleeVReg);
26362
- MI.getOperand(0).ChangeToES(Symbol);
26363
- MI.setDesc(TII->get(Opc));
26364
- } else {
26365
- BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), AvailableReg)
26366
- .addReg(CalleeVReg);
26367
- MI.getOperand(0).ChangeToES(Symbol);
26368
- MI.setDesc(TII->get(Opc));
26369
- MachineInstrBuilder(*BB->getParent(), &MI)
26370
- .addReg(AvailableReg, RegState::Implicit | RegState::Kill);
26371
- }
26352
+ BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), AvailableReg)
26353
+ .addReg(CalleeVReg);
26354
+ MI.getOperand(0).ChangeToES(Symbol);
26355
+ MI.setDesc(TII->get(Opc));
26356
+ MachineInstrBuilder(*BB->getParent(), &MI)
26357
+ .addReg(AvailableReg, RegState::Implicit | RegState::Kill);
26372
26358
return BB;
26373
26359
}
26374
26360
0 commit comments