diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86.td | 35 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FastISel.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 12 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrControl.td | 14 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrInfo.td | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86RetpolineThunks.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86Subtarget.h | 19 |
11 files changed, 68 insertions, 36 deletions
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 63c2dc4da6c..22ae131273d 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -362,17 +362,30 @@ def FeaturePrefer256Bit : SubtargetFeature<"prefer-256-bit", "Prefer256Bit", "true", "Prefer 256-bit AVX instructions">; -// Enable mitigation of some aspects of speculative execution related -// vulnerabilities by removing speculatable indirect branches. This disables -// jump-table formation, rewrites explicit `indirectbr` instructions into -// `switch` instructions, and uses a special construct called a "retpoline" to -// prevent speculation of the remaining indirect branches (indirect calls and -// tail calls). +// Lower indirect calls using a special construct called a `retpoline` to +// mitigate potential Spectre v2 attacks against them. +def FeatureRetpolineIndirectCalls + : SubtargetFeature< + "retpoline-indirect-calls", "UseRetpolineIndirectCalls", "true", + "Remove speculation of indirect calls from the generated code.">; + +// Lower indirect branches and switches either using conditional branch trees +// or using a special construct called a `retpoline` to mitigate potential +// Spectre v2 attacks against them. +def FeatureRetpolineIndirectBranches + : SubtargetFeature< + "retpoline-indirect-branches", "UseRetpolineIndirectBranches", "true", + "Remove speculation of indirect branches from the generated code.">; + +// Deprecated umbrella feature for enabling both `retpoline-indirect-calls` and +// `retpoline-indirect-branches` above. def FeatureRetpoline - : SubtargetFeature<"retpoline", "UseRetpoline", "true", + : SubtargetFeature<"retpoline", "DeprecatedUseRetpoline", "true", "Remove speculation of indirect branches from the " "generated code, either by avoiding them entirely or " - "lowering them with a speculation blocking construct.">; + "lowering them with a speculation blocking construct.", + [FeatureRetpolineIndirectCalls, + FeatureRetpolineIndirectBranches]>; // Rely on external thunks for the emitted retpoline calls. This allows users // to provide their own custom thunk definitions in highly specialized @@ -380,8 +393,10 @@ def FeatureRetpoline def FeatureRetpolineExternalThunk : SubtargetFeature< "retpoline-external-thunk", "UseRetpolineExternalThunk", "true", - "Enable retpoline, but with an externally provided thunk.", - [FeatureRetpoline]>; + "When lowering an indirect call or branch using a `retpoline`, rely " + "on the specified user provided thunk rather than emitting one " + "ourselves. Only has effect when combined with some other retpoline " + "feature.", [FeatureRetpolineIndirectCalls]>; // Direct Move instructions. def FeatureMOVDIRI : SubtargetFeature<"movdiri", "HasMOVDIRI", "true", diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index d082b42eefa..d085eb69421 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -3222,8 +3222,8 @@ bool X86FastISel::fastLowerCall(CallLoweringInfo &CLI) { (CalledFn && CalledFn->hasFnAttribute("no_caller_saved_registers"))) return false; - // Functions using retpoline should use SDISel for calls. - if (Subtarget->useRetpoline()) + // Functions using retpoline for indirect calls need to use SDISel. + if (Subtarget->useRetpolineIndirectCalls()) return false; // Handle only C, fastcc, and webkit_js calling conventions for now. diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index e207c343fac..46e30d786f0 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -765,7 +765,7 @@ void X86FrameLowering::emitStackProbeCall(MachineFunction &MF, bool IsLargeCodeModel = MF.getTarget().getCodeModel() == CodeModel::Large; // FIXME: Add retpoline support and remove this. - if (Is64Bit && IsLargeCodeModel && STI.useRetpoline()) + if (Is64Bit && IsLargeCodeModel && STI.useRetpolineIndirectCalls()) report_fatal_error("Emitting stack probe calls on 64-bit with the large " "code model and retpoline not yet implemented."); @@ -2437,7 +2437,7 @@ void X86FrameLowering::adjustForSegmentedStacks( // is laid out within 2^31 bytes of each function body, but this seems // to be sufficient for JIT. // FIXME: Add retpoline support and remove the error here.. - if (STI.useRetpoline()) + if (STI.useRetpolineIndirectCalls()) report_fatal_error("Emitting morestack calls on 64-bit with the large " "code model and retpoline not yet implemented."); BuildMI(allocMBB, DL, TII.get(X86::CALL64m)) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 80d8183346b..7236fdeb8be 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -725,7 +725,7 @@ void X86DAGToDAGISel::PreprocessISelDAG() { if (OptLevel != CodeGenOpt::None && // Only do this when the target can fold the load into the call or // jmp. - !Subtarget->useRetpoline() && + !Subtarget->useRetpolineIndirectCalls() && ((N->getOpcode() == X86ISD::CALL && !Subtarget->slowTwoMemOps()) || (N->getOpcode() == X86ISD::TC_RETURN && (Subtarget->is64Bit() || diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 0c5e4df2d3c..2ffc9566ed0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -26649,7 +26649,7 @@ bool X86TargetLowering::isVectorClearMaskLegal(ArrayRef<int> Mask, bool X86TargetLowering::areJTsAllowed(const Function *Fn) const { // If the subtarget is using retpolines, we need to not generate jump tables. - if (Subtarget.useRetpoline()) + if (Subtarget.useRetpolineIndirectBranches()) return false; // Otherwise, fallback on the generic logic. diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 7c01714b6a0..0ff73101dcc 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -1095,14 +1095,14 @@ def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), (TCRETURNri ptr_rc_tailcall:$dst, imm:$off)>, - Requires<[Not64BitMode, NotUseRetpoline]>; + Requires<[Not64BitMode, NotUseRetpolineIndirectCalls]>; // FIXME: This is disabled for 32-bit PIC mode because the global base // register which is part of the address mode may be assigned a // callee-saved register. def : Pat<(X86tcret (load addr:$dst), imm:$off), (TCRETURNmi addr:$dst, imm:$off)>, - Requires<[Not64BitMode, IsNotPIC, NotUseRetpoline]>; + Requires<[Not64BitMode, IsNotPIC, NotUseRetpolineIndirectCalls]>; def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off), (TCRETURNdi tglobaladdr:$dst, imm:$off)>, @@ -1114,21 +1114,21 @@ def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off), def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), (TCRETURNri64 ptr_rc_tailcall:$dst, imm:$off)>, - Requires<[In64BitMode, NotUseRetpoline]>; + Requires<[In64BitMode, NotUseRetpolineIndirectCalls]>; // Don't fold loads into X86tcret requiring more than 6 regs. // There wouldn't be enough scratch registers for base+index. def : Pat<(X86tcret_6regs (load addr:$dst), imm:$off), (TCRETURNmi64 addr:$dst, imm:$off)>, - Requires<[In64BitMode, NotUseRetpoline]>; + Requires<[In64BitMode, NotUseRetpolineIndirectCalls]>; def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), (RETPOLINE_TCRETURN64 ptr_rc_tailcall:$dst, imm:$off)>, - Requires<[In64BitMode, UseRetpoline]>; + Requires<[In64BitMode, UseRetpolineIndirectCalls]>; def : Pat<(X86tcret ptr_rc_tailcall:$dst, imm:$off), (RETPOLINE_TCRETURN32 ptr_rc_tailcall:$dst, imm:$off)>, - Requires<[Not64BitMode, UseRetpoline]>; + Requires<[Not64BitMode, UseRetpolineIndirectCalls]>; def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off), (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>, diff --git a/llvm/lib/Target/X86/X86InstrControl.td b/llvm/lib/Target/X86/X86InstrControl.td index 650bce74dcf..a7c7aaab228 100644 --- a/llvm/lib/Target/X86/X86InstrControl.td +++ b/llvm/lib/Target/X86/X86InstrControl.td @@ -222,11 +222,13 @@ let isCall = 1 in Sched<[WriteJumpLd]>; def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst), "call{l}\t{*}$dst", [(X86call GR32:$dst)]>, OpSize32, - Requires<[Not64BitMode,NotUseRetpoline]>, Sched<[WriteJump]>; + Requires<[Not64BitMode,NotUseRetpolineIndirectCalls]>, + Sched<[WriteJump]>; def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst), "call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))]>, OpSize32, - Requires<[Not64BitMode,FavorMemIndirectCall,NotUseRetpoline]>, + Requires<[Not64BitMode,FavorMemIndirectCall, + NotUseRetpolineIndirectCalls]>, Sched<[WriteJumpLd]>; // Non-tracking calls for IBT, use with caution. @@ -320,11 +322,11 @@ let isCall = 1, Uses = [RSP, SSP], SchedRW = [WriteJump] in { Requires<[In64BitMode]>; def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst), "call{q}\t{*}$dst", [(X86call GR64:$dst)]>, - Requires<[In64BitMode,NotUseRetpoline]>; + Requires<[In64BitMode,NotUseRetpolineIndirectCalls]>; def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst), "call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))]>, Requires<[In64BitMode,FavorMemIndirectCall, - NotUseRetpoline]>; + NotUseRetpolineIndirectCalls]>; // Non-tracking calls for IBT, use with caution. let isCodeGenOnly = 1 in { @@ -379,11 +381,11 @@ let isPseudo = 1, isCall = 1, isCodeGenOnly = 1, SchedRW = [WriteJump] in { def RETPOLINE_CALL32 : PseudoI<(outs), (ins GR32:$dst), [(X86call GR32:$dst)]>, - Requires<[Not64BitMode,UseRetpoline]>; + Requires<[Not64BitMode,UseRetpolineIndirectCalls]>; def RETPOLINE_CALL64 : PseudoI<(outs), (ins GR64:$dst), [(X86call GR64:$dst)]>, - Requires<[In64BitMode,UseRetpoline]>; + Requires<[In64BitMode,UseRetpolineIndirectCalls]>; // Retpoline variant of indirect tail calls. let isTerminator = 1, isReturn = 1, isBarrier = 1 in { diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index b1ef2c565a5..bbc4e2bdd68 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -955,8 +955,8 @@ def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">; def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">; def HasERMSB : Predicate<"Subtarget->hasERMSB()">; def HasMFence : Predicate<"Subtarget->hasMFence()">; -def UseRetpoline : Predicate<"Subtarget->useRetpoline()">; -def NotUseRetpoline : Predicate<"!Subtarget->useRetpoline()">; +def UseRetpolineIndirectCalls : Predicate<"Subtarget->useRetpolineIndirectCalls()">; +def NotUseRetpolineIndirectCalls : Predicate<"!Subtarget->useRetpolineIndirectCalls()">; //===----------------------------------------------------------------------===// // X86 Instruction Format Definitions. diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 343bef0e919..1e4ced13bb7 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -898,7 +898,7 @@ void X86AsmPrinter::LowerSTATEPOINT(const MachineInstr &MI, break; case MachineOperand::MO_Register: // FIXME: Add retpoline support and remove this. - if (Subtarget->useRetpoline()) + if (Subtarget->useRetpolineIndirectCalls()) report_fatal_error("Lowering register statepoints with retpoline not " "yet implemented."); CallTargetMCOp = MCOperand::createReg(CallTarget.getReg()); @@ -1055,7 +1055,7 @@ void X86AsmPrinter::LowerPATCHPOINT(const MachineInstr &MI, EmitAndCountInstruction( MCInstBuilder(X86::MOV64ri).addReg(ScratchReg).addOperand(CalleeMCOp)); // FIXME: Add retpoline support and remove this. - if (Subtarget->useRetpoline()) + if (Subtarget->useRetpolineIndirectCalls()) report_fatal_error( "Lowering patchpoint with retpoline not yet implemented."); EmitAndCountInstruction(MCInstBuilder(X86::CALL64r).addReg(ScratchReg)); diff --git a/llvm/lib/Target/X86/X86RetpolineThunks.cpp b/llvm/lib/Target/X86/X86RetpolineThunks.cpp index 250deb3523b..f62e89eb1ba 100644 --- a/llvm/lib/Target/X86/X86RetpolineThunks.cpp +++ b/llvm/lib/Target/X86/X86RetpolineThunks.cpp @@ -115,7 +115,9 @@ bool X86RetpolineThunks::runOnMachineFunction(MachineFunction &MF) { // FIXME: It's a little silly to look at every function just to enumerate // the subtargets, but eventually we'll want to look at them for indirect // calls, so maybe this is OK. - if (!STI->useRetpoline() || STI->useRetpolineExternalThunk()) + if ((!STI->useRetpolineIndirectCalls() && + !STI->useRetpolineIndirectBranches()) || + STI->useRetpolineExternalThunk()) return false; // Otherwise, we need to insert the thunk. diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 85e8256a6e9..e52708687c6 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -387,7 +387,15 @@ protected: /// Use a retpoline thunk rather than indirect calls to block speculative /// execution. - bool UseRetpoline = false; + bool UseRetpolineIndirectCalls = false; + + /// Use a retpoline thunk or remove any indirect branch to block speculative + /// execution. + bool UseRetpolineIndirectBranches = false; + + /// Deprecated flag, query `UseRetpolineIndirectCalls` and + /// `UseRetpolineIndirectBranches` instead. + bool DeprecatedUseRetpoline = false; /// When using a retpoline thunk, call an externally provided thunk rather /// than emitting one inside the compiler. @@ -649,7 +657,10 @@ public: bool hasPCONFIG() const { return HasPCONFIG; } bool hasSGX() const { return HasSGX; } bool hasINVPCID() const { return HasINVPCID; } - bool useRetpoline() const { return UseRetpoline; } + bool useRetpolineIndirectCalls() const { return UseRetpolineIndirectCalls; } + bool useRetpolineIndirectBranches() const { + return UseRetpolineIndirectBranches; + } bool useRetpolineExternalThunk() const { return UseRetpolineExternalThunk; } unsigned getPreferVectorWidth() const { return PreferVectorWidth; } @@ -804,7 +815,9 @@ public: /// If we are using retpolines, we need to expand indirectbr to avoid it /// lowering to an actual indirect jump. - bool enableIndirectBrExpand() const override { return useRetpoline(); } + bool enableIndirectBrExpand() const override { + return useRetpolineIndirectBranches(); + } /// Enable the MachineScheduler pass for all X86 subtargets. bool enableMachineScheduler() const override { return true; } |