Index: include/llvm/IR/IntrinsicsX86.td =================================================================== --- include/llvm/IR/IntrinsicsX86.td +++ include/llvm/IR/IntrinsicsX86.td @@ -63,6 +63,12 @@ Intrinsic<[llvm_i64_ty], [llvm_i32_ty], []>; } +// Read processor ID. +let TargetPrefix = "x86" in { + def int_x86_rdpid : GCCBuiltin<"__builtin_ia32_rdpid">, + Intrinsic<[llvm_i32_ty], [], []>; +} + //===----------------------------------------------------------------------===// // CET SS let TargetPrefix = "x86" in { Index: lib/Support/Host.cpp =================================================================== --- lib/Support/Host.cpp +++ lib/Support/Host.cpp @@ -1255,7 +1255,9 @@ Features["avx512vnni"] = HasLeaf7 && ((ECX >> 11) & 1) && HasAVX512Save; Features["avx512bitalg"] = HasLeaf7 && ((ECX >> 12) & 1) && HasAVX512Save; Features["avx512vpopcntdq"] = HasLeaf7 && ((ECX >> 14) & 1) && HasAVX512Save; - Features["ibt"] = HasLeaf7 && ((EDX >> 20) & 1); + Features["rdpid"] = HasLeaf7 && ((ECX >> 22) & 1); + + Features["ibt"] = HasLeaf7 && ((EDX >> 20) & 1); bool HasLeafD = MaxLevel >= 0xd && !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX); Index: lib/Target/X86/X86.td =================================================================== --- lib/Target/X86/X86.td +++ lib/Target/X86/X86.td @@ -249,6 +249,8 @@ "Flush A Cache Line Optimized">; def FeatureCLWB : SubtargetFeature<"clwb", "HasCLWB", "true", "Cache Line Write Back">; +def FeatureRDPID : SubtargetFeature<"rdpid", "HasRDPID", "true", + "Support RDPID instructions">; // On some processors, instructions that implicitly take two memory operands are // slow. In practice, this means that CALL, PUSH, and POP with memory operands // should be avoided in favor of a MOV + register CALL/PUSH/POP. @@ -752,7 +754,8 @@ FeatureVPCLMULQDQ, FeatureVPOPCNTDQ, FeatureGFNI, - FeatureCLWB + FeatureCLWB, + FeatureRDPID ]>; class IcelakeProc : ProcModelhasIBT()">; def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">; def HasCLWB : Predicate<"Subtarget->hasCLWB()">; +def HasRDPID : Predicate<"Subtarget->hasRDPID()">; def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, AssemblerPredicate<"!Mode64Bit", "Not 64-bit mode">; Index: lib/Target/X86/X86InstrSystem.td =================================================================== --- lib/Target/X86/X86InstrSystem.td +++ lib/Target/X86/X86InstrSystem.td @@ -700,14 +700,22 @@ //===----------------------------------------------------------------------===// // RDPID Instruction let SchedRW = [WriteSystem] in { -def RDPID32 : I<0xC7, MRM7r, (outs GR32:$src), (ins), - "rdpid\t$src", [], IIC_RDPID>, XS, - Requires<[Not64BitMode]>; -def RDPID64 : I<0xC7, MRM7r, (outs GR64:$src), (ins), - "rdpid\t$src", [], IIC_RDPID>, XS, - Requires<[In64BitMode]>; +def RDPID32 : I<0xC7, MRM7r, (outs GR32:$dst), (ins), + "rdpid\t$dst", [(set GR32:$dst, (int_x86_rdpid))], IIC_RDPID>, XS, + Requires<[Not64BitMode, HasRDPID]>; +def RDPID64 : I<0xC7, MRM7r, (outs GR64:$dst), (ins), + "rdpid\t$dst", [], IIC_RDPID>, XS, + Requires<[In64BitMode, HasRDPID]>; } // SchedRW +let Predicates = [In64BitMode, HasRDPID] in { + // Due to silly instruction definition, we have to compensate for the + // instruction outputing a 64-bit register. + def : Pat<(int_x86_rdpid), + (EXTRACT_SUBREG (RDPID64), sub_32bit)>; +} + + //===----------------------------------------------------------------------===// // PTWRITE Instruction let SchedRW = [WriteSystem] in { Index: lib/Target/X86/X86Subtarget.h =================================================================== --- lib/Target/X86/X86Subtarget.h +++ lib/Target/X86/X86Subtarget.h @@ -345,6 +345,9 @@ /// Processor supports Cache Line Write Back instruction bool HasCLWB; + /// Processor support RDPID instruction + bool HasRDPID; + /// Use software floating point for code generation. bool UseSoftFloat; @@ -579,6 +582,7 @@ bool hasIBT() const { return HasIBT; } bool hasCLFLUSHOPT() const { return HasCLFLUSHOPT; } bool hasCLWB() const { return HasCLWB; } + bool hasRDPID() const { return HasRDPID; } bool isXRaySupported() const override { return is64Bit(); } Index: lib/Target/X86/X86Subtarget.cpp =================================================================== --- lib/Target/X86/X86Subtarget.cpp +++ lib/Target/X86/X86Subtarget.cpp @@ -315,6 +315,7 @@ HasSGX = false; HasCLFLUSHOPT = false; HasCLWB = false; + HasRDPID = false; IsPMULLDSlow = false; IsSHLDSlow = false; IsUAMem16Slow = false; Index: test/CodeGen/X86/rdpid.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/rdpid.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- -mattr=rdpid | FileCheck %s --check-prefix=CHECK --check-prefix=X86-64 +; RUN: llc < %s -mtriple=i686-- -mattr=rdpid | FileCheck %s --check-prefix=CHECK --check-prefix=X86 + +define i32 @test_builtin_rdpid() { +; X86-64-LABEL: test_builtin_rdpid: +; X86-64: # %bb.0: +; X86-64-NEXT: rdpid %rax +; X86-64-NEXT: # kill: def %eax killed %eax killed %rax +; X86-64-NEXT: retq +; +; X86-LABEL: test_builtin_rdpid: +; X86: # %bb.0: +; X86-NEXT: rdpid %eax +; X86-NEXT: retl + %1 = tail call i32 @llvm.x86.rdpid() + ret i32 %1 +} + +declare i32 @llvm.x86.rdpid() +