diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 42f61fed74fb..512c56b97400 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -145,7 +145,24 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID, .getResult(); } case X86::BI__builtin_ia32_rdtscp: { - llvm_unreachable("__rdtscp NYI"); + // For rdtscp, we need to create a proper struct type to hold {i64, i32} + cir::RecordType resTy = builder.getAnonRecordTy( + {builder.getUInt64Ty(), builder.getUInt32Ty()}, false, false); + + auto call = builder + .create( + getLoc(E->getExprLoc()), + builder.getStringAttr("x86.rdtscp"), resTy) + .getResult(); + + // Store processor ID in address param + mlir::Value pID = builder.create( + getLoc(E->getExprLoc()), builder.getUInt32Ty(), call, 1); + builder.create(getLoc(E->getExprLoc()), pID, Ops[0]); + + // Return the timestamp at index 0 + return builder.create(getLoc(E->getExprLoc()), + builder.getUInt64Ty(), call, 0); } case X86::BI__builtin_ia32_lzcnt_u16: case X86::BI__builtin_ia32_lzcnt_u32: diff --git a/clang/test/CIR/CodeGen/X86/builtins-x86.c b/clang/test/CIR/CodeGen/X86/builtins-x86.c index eeebec717bcd..c8d00aaf3bf2 100644 --- a/clang/test/CIR/CodeGen/X86/builtins-x86.c +++ b/clang/test/CIR/CodeGen/X86/builtins-x86.c @@ -45,12 +45,3 @@ void test_mm_sfence() { // CIR: {{%.*}} = cir.llvm.intrinsic "x86.sse.sfence" : () -> !void // LLVM: call void @llvm.x86.sse.sfence() } - -unsigned long long test_rdtsc() { - // CIR-LABEL: @test_rdtsc - // LLVM-LABEL: @test_rdtsc - return __rdtsc(); - // CIR: {{%.*}} = cir.llvm.intrinsic "x86.rdtsc" : () -> !u64i - // LLVM: call i64 @llvm.x86.rdtsc -} - diff --git a/clang/test/CIR/CodeGen/X86/rd-builtins.c b/clang/test/CIR/CodeGen/X86/rd-builtins.c new file mode 100644 index 000000000000..8f8902199b10 --- /dev/null +++ b/clang/test/CIR/CodeGen/X86/rd-builtins.c @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +// This test mimics clang/test/CodeGen/X86/rd-builtins.c, which eventually +// CIR shall be able to support fully. + +#include + +unsigned long long test_rdtsc() { + // CIR-LABEL: @test_rdtsc + // LLVM-LABEL: @test_rdtsc + return __rdtsc(); + // CIR: {{%.*}} = cir.llvm.intrinsic "x86.rdtsc" : () -> !u64i + // LLVM: call i64 @llvm.x86.rdtsc +} + +unsigned long long test_rdtscp(unsigned int *a) { + + return __rdtscp(a); + + // CIR-LABEL: @__rdtscp + // CIR: [[RDTSCP:%.*]] = cir.llvm.intrinsic "x86.rdtscp" : () -> !rec_anon_struct + // CIR: [[TSC_AUX:%.*]] = cir.extract_member [[RDTSCP]][1] : !rec_anon_struct -> !u32i + // CIR: cir.store [[TSC_AUX]], %{{.*}} : !u32i, !cir.ptr + // CIR: {{%.*}} = cir.extract_member [[RDTSCP]][0] : !rec_anon_struct -> !u64i + + // LLVM: @test_rdtscp + // LLVM: [[RDTSCP:%.*]] = call { i64, i32 } @llvm.x86.rdtscp + // LLVM: [[TSC_AUX:%.*]] = extractvalue { i64, i32 } [[RDTSCP]], 1 + // LLVM: store i32 [[TSC_AUX]], ptr %{{.*}} + // LLVM: [[TSC:%.*]] = extractvalue { i64, i32 } [[RDTSCP]], 0 +} +