diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-07-03 14:10:23 +0000 |
commit | 145449b1e420787bb99721a429341fa6be3adfb6 (patch) | |
tree | 1d56ae694a6de602e348dd80165cf881a36600ed /llvm/lib/Target/X86/X86InstrCompiler.td | |
parent | ecbca9f5fb7d7613d2b94982c4825eb0d33d6842 (diff) | |
download | src-145449b1e420787bb99721a429341fa6be3adfb6.tar.gz src-145449b1e420787bb99721a429341fa6be3adfb6.zip |
Vendor import of llvm-project main llvmorg-15-init-15358-g53dc0f107877.vendor/llvm-project/llvmorg-15-init-15358-g53dc0f107877
Diffstat (limited to 'llvm/lib/Target/X86/X86InstrCompiler.td')
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 85 |
1 files changed, 75 insertions, 10 deletions
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index 7288ce812138..a55b95960aa6 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -544,10 +544,10 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS] in { // i8 register pressure. defm _GR8 : CMOVrr_PSEUDO<GR8, i8>; - let Predicates = [NoCMov] in { + let Predicates = [NoCMOV] in { defm _GR32 : CMOVrr_PSEUDO<GR32, i32>; defm _GR16 : CMOVrr_PSEUDO<GR16, i16>; - } // Predicates = [NoCMov] + } // Predicates = [NoCMOV] // fcmov doesn't handle all possible EFLAGS, provide a fallback if there is no // SSE1/SSE2. @@ -562,12 +562,14 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Uses = [EFLAGS] in { let Predicates = [HasMMX] in defm _VR64 : CMOVrr_PSEUDO<VR64, x86mmx>; - defm _FR16X : CMOVrr_PSEUDO<FR16X, f16>; let Predicates = [HasSSE1,NoAVX512] in defm _FR32 : CMOVrr_PSEUDO<FR32, f32>; - let Predicates = [HasSSE2,NoAVX512] in + let Predicates = [HasSSE2,NoAVX512] in { + defm _FR16 : CMOVrr_PSEUDO<FR16, f16>; defm _FR64 : CMOVrr_PSEUDO<FR64, f64>; + } let Predicates = [HasAVX512] in { + defm _FR16X : CMOVrr_PSEUDO<FR16X, f16>; defm _FR32X : CMOVrr_PSEUDO<FR32X, f32>; defm _FR64X : CMOVrr_PSEUDO<FR64X, f64>; } @@ -670,7 +672,7 @@ def OR32mi8Locked : Ii8<0x83, MRM1m, (outs), (ins i32mem:$dst, i32i8imm:$zero), Requires<[Not64BitMode]>, OpSize32, LOCK, Sched<[WriteALURMW]>; -let hasSideEffects = 1 in +let hasSideEffects = 1, isMeta = 1 in def Int_MemBarrier : I<0, Pseudo, (outs), (ins), "#MEMBARRIER", [(X86MemBarrier)]>, Sched<[WriteLoad]>; @@ -839,6 +841,38 @@ let Predicates = [UseIncDec] in { def : Pat<(X86lock_sub addr:$dst, (i64 -1)), (LOCK_INC64m addr:$dst)>; } +// Atomic bit test. +def X86LBTest : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisPtrTy<1>, + SDTCisVT<2, i8>, SDTCisVT<3, i32>]>; +def x86bts : SDNode<"X86ISD::LBTS", X86LBTest, + [SDNPHasChain, SDNPMayLoad, SDNPMayStore, SDNPMemOperand]>; +def x86btc : SDNode<"X86ISD::LBTC", X86LBTest, + [SDNPHasChain, SDNPMayLoad, SDNPMayStore, SDNPMemOperand]>; +def x86btr : SDNode<"X86ISD::LBTR", X86LBTest, + [SDNPHasChain, SDNPMayLoad, SDNPMayStore, SDNPMemOperand]>; + +multiclass ATOMIC_LOGIC_OP<Format Form, string s> { + let Defs = [EFLAGS], mayLoad = 1, mayStore = 1, isCodeGenOnly = 1, + SchedRW = [WriteBitTestSetRegRMW] in { + def 16m : Ii8<0xBA, Form, (outs), (ins i16mem:$src1, i8imm:$src2), + !strconcat(s, "{w}\t{$src2, $src1|$src1, $src2}"), + [(set EFLAGS, (!cast<SDNode>("x86" # s) addr:$src1, timm:$src2, (i32 16)))]>, + OpSize16, TB, LOCK; + def 32m : Ii8<0xBA, Form, (outs), (ins i32mem:$src1, i8imm:$src2), + !strconcat(s, "{l}\t{$src2, $src1|$src1, $src2}"), + [(set EFLAGS, (!cast<SDNode>("x86" # s) addr:$src1, timm:$src2, (i32 32)))]>, + OpSize32, TB, LOCK; + def 64m : RIi8<0xBA, Form, (outs), (ins i64mem:$src1, i8imm:$src2), + !strconcat(s, "{q}\t{$src2, $src1|$src1, $src2}"), + [(set EFLAGS, (!cast<SDNode>("x86" # s) addr:$src1, timm:$src2, (i32 64)))]>, + TB, LOCK; + } +} + +defm LOCK_BTS : ATOMIC_LOGIC_OP<MRM5m, "bts">; +defm LOCK_BTC : ATOMIC_LOGIC_OP<MRM7m, "btc">; +defm LOCK_BTR : ATOMIC_LOGIC_OP<MRM6m, "btr">; + // Atomic compare and swap. multiclass LCMPXCHG_BinOp<bits<8> Opc8, bits<8> Opc, Format Form, string mnemonic, SDPatternOperator frag> { @@ -863,7 +897,7 @@ let isCodeGenOnly = 1, SchedRW = [WriteCMPXCHGRMW] in { } let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX], - Predicates = [HasCmpxchg8b], SchedRW = [WriteCMPXCHGRMW], + Predicates = [HasCX8], SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, usesCustomInserter = 1 in { def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr), "cmpxchg8b\t$ptr", @@ -871,7 +905,7 @@ def LCMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$ptr), } let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX], - Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW], + Predicates = [HasCX16,In64BitMode], SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, mayLoad = 1, mayStore = 1, hasSideEffects = 0 in { def LCMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$ptr), "cmpxchg16b\t$ptr", @@ -898,7 +932,7 @@ def LCMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$ptr), // the instruction and we are sure we will have a valid register to restore // the value of RBX. let Defs = [RAX, RDX, RBX, EFLAGS], Uses = [RAX, RCX, RDX], - Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW], + Predicates = [HasCX16,In64BitMode], SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$rbx_save = $dst" in { @@ -910,7 +944,7 @@ def LCMPXCHG16B_SAVE_RBX : // Pseudo instruction that doesn't read/write RBX. Will be turned into either // LCMPXCHG16B_SAVE_RBX or LCMPXCHG16B via a custom inserter. let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RCX, RDX], - Predicates = [HasCmpxchg16b,In64BitMode], SchedRW = [WriteCMPXCHGRMW], + Predicates = [HasCX16,In64BitMode], SchedRW = [WriteCMPXCHGRMW], isCodeGenOnly = 1, isPseudo = 1, mayLoad = 1, mayStore = 1, hasSideEffects = 0, usesCustomInserter = 1 in { @@ -1235,6 +1269,21 @@ def X86tcret_6regs : PatFrag<(ops node:$ptr, node:$off), return true; }]>; +def X86tcret_1reg : PatFrag<(ops node:$ptr, node:$off), + (X86tcret node:$ptr, node:$off), [{ + // X86tcret args: (*chain, ptr, imm, regs..., glue) + unsigned NumRegs = 1; + const SDValue& BasePtr = cast<LoadSDNode>(N->getOperand(1))->getBasePtr(); + if (isa<FrameIndexSDNode>(BasePtr)) + NumRegs = 3; + else if (BasePtr->getNumOperands() && isa<GlobalAddressSDNode>(BasePtr->getOperand(0))) + NumRegs = 3; + for (unsigned i = 3, e = N->getNumOperands(); i != e; ++i) + if (isa<RegisterSDNode>(N->getOperand(i)) && ( NumRegs-- == 0)) + return false; + return true; +}]>; + def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off), (TCRETURNri ptr_rc_tailcall:$dst, timm:$off)>, Requires<[Not64BitMode, NotUseIndirectThunkCalls]>; @@ -1242,7 +1291,8 @@ def : Pat<(X86tcret ptr_rc_tailcall:$dst, timm:$off), // 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), timm:$off), +// Similar to X86tcret_6regs, here we only have 1 register left +def : Pat<(X86tcret_1reg (load addr:$dst), timm:$off), (TCRETURNmi addr:$dst, timm:$off)>, Requires<[Not64BitMode, IsNotPIC, NotUseIndirectThunkCalls]>; @@ -1467,6 +1517,21 @@ def ADD64ri32_DB : I<0, Pseudo, } // AddedComplexity, SchedRW //===----------------------------------------------------------------------===// +// Pattern match XOR as ADD +//===----------------------------------------------------------------------===// + +// Prefer to pattern match XOR with min_signed_value as ADD at isel time. +// ADD can be 3-addressified into an LEA instruction to avoid copies. +let AddedComplexity = 5 in { +def : Pat<(xor GR8:$src1, -128), + (ADD8ri GR8:$src1, -128)>; +def : Pat<(xor GR16:$src1, -32768), + (ADD16ri GR16:$src1, -32768)>; +def : Pat<(xor GR32:$src1, -2147483648), + (ADD32ri GR32:$src1, -2147483648)>; +} + +//===----------------------------------------------------------------------===// // Pattern match SUB as XOR //===----------------------------------------------------------------------===// |