diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-31 21:22:58 +0000 |
commit | 5ffd83dbcc34f10e07f6d3e968ae6365869615f4 (patch) | |
tree | 0e9f5cf729dde39f949698fddef45a34e2bc7f44 /contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td | |
parent | 1799696096df87b52968b8996d00c91e0a5de8d9 (diff) | |
parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
download | src-5ffd83dbcc34f10e07f6d3e968ae6365869615f4.tar.gz src-5ffd83dbcc34f10e07f6d3e968ae6365869615f4.zip |
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
master 2e10b7a39b9, the last commit before the llvmorg-12-init tag, from
which release/11.x was branched.
Note that for now, I rolled back all our local changes to make merging
easier, and I will reapply the still-relevant ones after updating to
11.0.0-rc1.
Notes
Notes:
svn path=/projects/clang1100-import/; revision=363742
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td | 157 |
1 files changed, 59 insertions, 98 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td index 1fdac104cb73..4df93fb2ed60 100644 --- a/contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/contrib/llvm-project/llvm/lib/Target/X86/X86InstrCompiler.td @@ -111,8 +111,30 @@ def SEG_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size), [(set GR64:$dst, (X86SegAlloca GR64:$size))]>, Requires<[In64BitMode]>; + +// To protect against stack clash, dynamic allocation should perform a memory +// probe at each page. + +let Defs = [EAX, ESP, EFLAGS], Uses = [ESP] in +def PROBED_ALLOCA_32 : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$size), + "# variable sized alloca with probing", + [(set GR32:$dst, + (X86ProbedAlloca GR32:$size))]>, + Requires<[NotLP64]>; + +let Defs = [RAX, RSP, EFLAGS], Uses = [RSP] in +def PROBED_ALLOCA_64 : I<0, Pseudo, (outs GR64:$dst), (ins GR64:$size), + "# variable sized alloca with probing", + [(set GR64:$dst, + (X86ProbedAlloca GR64:$size))]>, + Requires<[In64BitMode]>; } +let hasNoSchedulingInfo = 1 in +def STACKALLOC_W_PROBING : I<0, Pseudo, (outs), (ins i64imm:$stacksize), + "# fixed size alloca with probing", + []>; + // Dynamic stack allocation yields a _chkstk or _alloca call for all Windows // targets. These calls are needed to probe the stack when allocating more than // 4k bytes in one go. Touching the stack at 4K increments is necessary to @@ -177,18 +199,6 @@ let isTerminator = 1, hasSideEffects = 1, isBarrier = 1, hasCtrlDep = 1, [(catchret bb:$dst, bb:$from)]>; } -let hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1, - usesCustomInserter = 1 in -def CATCHPAD : I<0, Pseudo, (outs), (ins), "# CATCHPAD", [(catchpad)]>; - -// This instruction is responsible for re-establishing stack pointers after an -// exception has been caught and we are rejoining normal control flow in the -// parent function or funclet. It generally sets ESP and EBP, and optionally -// ESI. It is only needed for 32-bit WinEH, as the runtime restores CSRs for us -// elsewhere. -let hasSideEffects = 1, hasCtrlDep = 1, isCodeGenOnly = 1 in -def EH_RESTORE : I<0, Pseudo, (outs), (ins), "# EH_RESTORE", []>; - let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1, usesCustomInserter = 1 in { def EH_SjLj_SetJmp32 : I<0, Pseudo, (outs GR32:$dst), (ins i32mem:$buf), @@ -308,69 +318,26 @@ def MOV64ImmSExti8 : I<0, Pseudo, (outs GR64:$dst), (ins i64i8imm:$src), "", // Materialize i64 constant where top 32-bits are zero. This could theoretically // use MOV32ri with a SUBREG_TO_REG to represent the zero-extension, however // that would make it more difficult to rematerialize. -let isReMaterializable = 1, isAsCheapAsAMove = 1, - isPseudo = 1, hasSideEffects = 0, SchedRW = [WriteMove] in -def MOV32ri64 : I<0, Pseudo, (outs GR64:$dst), (ins i64i32imm:$src), "", []>; - -// This 64-bit pseudo-move can be used for both a 64-bit constant that is -// actually the zero-extension of a 32-bit constant and for labels in the -// x86-64 small code model. -def mov64imm32 : ComplexPattern<i64, 1, "selectMOV64Imm32", [imm, X86Wrapper]>; - +let AddedComplexity = 1, isReMaterializable = 1, isAsCheapAsAMove = 1, + isPseudo = 1, SchedRW = [WriteMove] in +def MOV32ri64 : I<0, Pseudo, (outs GR64:$dst), (ins i64i32imm:$src), "", + [(set GR64:$dst, i64immZExt32:$src)]>; + +// This 64-bit pseudo-move can also be used for labels in the x86-64 small code +// model. +def mov64imm32 : ComplexPattern<i64, 1, "selectMOV64Imm32", [X86Wrapper]>; def : Pat<(i64 mov64imm32:$src), (MOV32ri64 mov64imm32:$src)>; // Use sbb to materialize carry bit. -let Uses = [EFLAGS], Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteALU] in { +let Uses = [EFLAGS], Defs = [EFLAGS], isPseudo = 1, SchedRW = [WriteADC], + hasSideEffects = 0 in { // FIXME: These are pseudo ops that should be replaced with Pat<> patterns. // However, Pat<> can't replicate the destination reg into the inputs of the // result. -def SETB_C8r : I<0, Pseudo, (outs GR8:$dst), (ins), "", - [(set GR8:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; -def SETB_C16r : I<0, Pseudo, (outs GR16:$dst), (ins), "", - [(set GR16:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; -def SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "", - [(set GR32:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; -def SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "", - [(set GR64:$dst, (X86setcc_c X86_COND_B, EFLAGS))]>; +def SETB_C32r : I<0, Pseudo, (outs GR32:$dst), (ins), "", []>; +def SETB_C64r : I<0, Pseudo, (outs GR64:$dst), (ins), "", []>; } // isCodeGenOnly - -def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C16r)>; -def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C32r)>; -def : Pat<(i64 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C64r)>; - -def : Pat<(i16 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C16r)>; -def : Pat<(i32 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C32r)>; -def : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C64r)>; - -// We canonicalize 'setb' to "(and (sbb reg,reg), 1)" on the hope that the and -// will be eliminated and that the sbb can be extended up to a wider type. When -// this happens, it is great. However, if we are left with an 8-bit sbb and an -// and, we might as well just match it as a setb. -def : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), - (SETCCr (i8 2))>; - -// Patterns to give priority when both inputs are zero so that we don't use -// an immediate for the RHS. -// TODO: Should we use a 32-bit sbb for 8/16 to push the extract_subreg out? -def : Pat<(X86sbb_flag (i8 0), (i8 0), EFLAGS), - (SBB8rr (EXTRACT_SUBREG (MOV32r0), sub_8bit), - (EXTRACT_SUBREG (MOV32r0), sub_8bit))>; -def : Pat<(X86sbb_flag (i16 0), (i16 0), EFLAGS), - (SBB16rr (EXTRACT_SUBREG (MOV32r0), sub_16bit), - (EXTRACT_SUBREG (MOV32r0), sub_16bit))>; -def : Pat<(X86sbb_flag (i32 0), (i32 0), EFLAGS), - (SBB32rr (MOV32r0), (MOV32r0))>; -def : Pat<(X86sbb_flag (i64 0), (i64 0), EFLAGS), - (SBB64rr (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit), - (SUBREG_TO_REG (i64 0), (MOV32r0), sub_32bit))>; - //===----------------------------------------------------------------------===// // String Pseudo Instructions // @@ -568,10 +535,13 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS] in { defm _RFP80 : CMOVrr_PSEUDO<RFP80, f80>; - let Predicates = [NoAVX512] in { + let Predicates = [HasMMX] in + defm _VR64 : CMOVrr_PSEUDO<VR64, x86mmx>; + + let Predicates = [HasSSE1,NoAVX512] in defm _FR32 : CMOVrr_PSEUDO<FR32, f32>; + let Predicates = [HasSSE2,NoAVX512] in defm _FR64 : CMOVrr_PSEUDO<FR64, f64>; - } let Predicates = [HasAVX512] in { defm _FR32X : CMOVrr_PSEUDO<FR32X, f32>; defm _FR64X : CMOVrr_PSEUDO<FR64X, f64>; @@ -585,6 +555,7 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS] in { defm _VR256X : CMOVrr_PSEUDO<VR256X, v4i64>; } defm _VR512 : CMOVrr_PSEUDO<VR512, v8i64>; + defm _VK1 : CMOVrr_PSEUDO<VK1, v1i1>; defm _VK2 : CMOVrr_PSEUDO<VK2, v2i1>; defm _VK4 : CMOVrr_PSEUDO<VK4, v4i1>; defm _VK8 : CMOVrr_PSEUDO<VK8, v8i1>; @@ -880,7 +851,7 @@ defm LCMPXCHG8B : LCMPXCHG_UnOp<0xC7, MRM1m, "cmpxchg8b", X86cas8, i64mem>; // it. In other words, the register will not fix the clobbering of // RBX that will happen when setting the arguments for the instrucion. // -// Unlike the actual related instuction, we mark that this one +// Unlike the actual related instruction, we mark that this one // defines EBX (instead of using EBX). // The rationale is that we will define RBX during the expansion of // the pseudo. The argument feeding EBX is ebx_input. @@ -1815,21 +1786,24 @@ multiclass MaskedRotateAmountPats<SDNode frag, string name> { defm : MaskedRotateAmountPats<rotl, "ROL">; defm : MaskedRotateAmountPats<rotr, "ROR">; -// Double shift amount is implicitly masked. -multiclass MaskedDoubleShiftAmountPats<SDNode frag, string name> { - // (shift x (and y, 31)) ==> (shift x, y) - def : Pat<(frag GR16:$src1, GR16:$src2, (shiftMask32 CL)), - (!cast<Instruction>(name # "16rrCL") GR16:$src1, GR16:$src2)>; - def : Pat<(frag GR32:$src1, GR32:$src2, (shiftMask32 CL)), - (!cast<Instruction>(name # "32rrCL") GR32:$src1, GR32:$src2)>; - - // (shift x (and y, 63)) ==> (shift x, y) - def : Pat<(frag GR64:$src1, GR64:$src2, (shiftMask32 CL)), - (!cast<Instruction>(name # "64rrCL") GR64:$src1, GR64:$src2)>; -} - -defm : MaskedDoubleShiftAmountPats<X86shld, "SHLD">; -defm : MaskedDoubleShiftAmountPats<X86shrd, "SHRD">; +// Double "funnel" shift amount is implicitly masked. +// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y) (NOTE: modulo32) +def : Pat<(X86fshl GR16:$src1, GR16:$src2, (shiftMask32 CL)), + (SHLD16rrCL GR16:$src1, GR16:$src2)>; +def : Pat<(X86fshr GR16:$src2, GR16:$src1, (shiftMask32 CL)), + (SHRD16rrCL GR16:$src1, GR16:$src2)>; + +// (fshl/fshr x (and y, 31)) ==> (fshl/fshr x, y) +def : Pat<(fshl GR32:$src1, GR32:$src2, (shiftMask32 CL)), + (SHLD32rrCL GR32:$src1, GR32:$src2)>; +def : Pat<(fshr GR32:$src2, GR32:$src1, (shiftMask32 CL)), + (SHRD32rrCL GR32:$src1, GR32:$src2)>; + +// (fshl/fshr x (and y, 63)) ==> (fshl/fshr x, y) +def : Pat<(fshl GR64:$src1, GR64:$src2, (shiftMask64 CL)), + (SHLD64rrCL GR64:$src1, GR64:$src2)>; +def : Pat<(fshr GR64:$src2, GR64:$src1, (shiftMask64 CL)), + (SHRD64rrCL GR64:$src1, GR64:$src2)>; let Predicates = [HasBMI2] in { let AddedComplexity = 1 in { @@ -1919,15 +1893,6 @@ defm : one_bit_patterns<GR16, i16, BTR16rr, BTS16rr, BTC16rr, shiftMask16>; defm : one_bit_patterns<GR32, i32, BTR32rr, BTS32rr, BTC32rr, shiftMask32>; defm : one_bit_patterns<GR64, i64, BTR64rr, BTS64rr, BTC64rr, shiftMask64>; - -// (anyext (setcc_carry)) -> (setcc_carry) -def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C16r)>; -def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C32r)>; -def : Pat<(i32 (anyext (i16 (X86setcc_c X86_COND_B, EFLAGS)))), - (SETB_C32r)>; - //===----------------------------------------------------------------------===// // EFLAGS-defining Patterns //===----------------------------------------------------------------------===// @@ -1999,10 +1964,6 @@ def : Pat<(X86sub_flag 0, GR16:$src), (NEG16r GR16:$src)>; def : Pat<(X86sub_flag 0, GR32:$src), (NEG32r GR32:$src)>; def : Pat<(X86sub_flag 0, GR64:$src), (NEG64r GR64:$src)>; -// sub reg, relocImm -def : Pat<(X86sub_flag GR64:$src1, i64relocImmSExt8_su:$src2), - (SUB64ri8 GR64:$src1, i64relocImmSExt8_su:$src2)>; - // mul reg, reg def : Pat<(mul GR16:$src1, GR16:$src2), (IMUL16rr GR16:$src1, GR16:$src2)>; |