Skip to content

Commit 076219a

Browse files
authored
[CIR][CIRGen][Builtin][X86] Lower __rdtscp (#1686)
Moved rd related intrinsic tests, to a different file similar to `clang/test/CodeGen/X86/rd-builtins.c`. Let me know if that's the right call. related: #1404
1 parent 32e3971 commit 076219a

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,24 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
145145
.getResult();
146146
}
147147
case X86::BI__builtin_ia32_rdtscp: {
148-
llvm_unreachable("__rdtscp NYI");
148+
// For rdtscp, we need to create a proper struct type to hold {i64, i32}
149+
cir::RecordType resTy = builder.getAnonRecordTy(
150+
{builder.getUInt64Ty(), builder.getUInt32Ty()}, false, false);
151+
152+
auto call = builder
153+
.create<cir::LLVMIntrinsicCallOp>(
154+
getLoc(E->getExprLoc()),
155+
builder.getStringAttr("x86.rdtscp"), resTy)
156+
.getResult();
157+
158+
// Store processor ID in address param
159+
mlir::Value pID = builder.create<cir::ExtractMemberOp>(
160+
getLoc(E->getExprLoc()), builder.getUInt32Ty(), call, 1);
161+
builder.create<cir::StoreOp>(getLoc(E->getExprLoc()), pID, Ops[0]);
162+
163+
// Return the timestamp at index 0
164+
return builder.create<cir::ExtractMemberOp>(getLoc(E->getExprLoc()),
165+
builder.getUInt64Ty(), call, 0);
149166
}
150167
case X86::BI__builtin_ia32_lzcnt_u16:
151168
case X86::BI__builtin_ia32_lzcnt_u32:

clang/test/CIR/CodeGen/X86/builtins-x86.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,3 @@ void test_mm_sfence() {
4545
// CIR: {{%.*}} = cir.llvm.intrinsic "x86.sse.sfence" : () -> !void
4646
// LLVM: call void @llvm.x86.sse.sfence()
4747
}
48-
49-
unsigned long long test_rdtsc() {
50-
// CIR-LABEL: @test_rdtsc
51-
// LLVM-LABEL: @test_rdtsc
52-
return __rdtsc();
53-
// CIR: {{%.*}} = cir.llvm.intrinsic "x86.rdtsc" : () -> !u64i
54-
// LLVM: call i64 @llvm.x86.rdtsc
55-
}
56-
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-cir -o %t.cir %s
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux -Wno-implicit-function-declaration -fclangir -emit-llvm -o %t.ll %s
4+
// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
5+
6+
// This test mimics clang/test/CodeGen/X86/rd-builtins.c, which eventually
7+
// CIR shall be able to support fully.
8+
9+
#include <x86intrin.h>
10+
11+
unsigned long long test_rdtsc() {
12+
// CIR-LABEL: @test_rdtsc
13+
// LLVM-LABEL: @test_rdtsc
14+
return __rdtsc();
15+
// CIR: {{%.*}} = cir.llvm.intrinsic "x86.rdtsc" : () -> !u64i
16+
// LLVM: call i64 @llvm.x86.rdtsc
17+
}
18+
19+
unsigned long long test_rdtscp(unsigned int *a) {
20+
21+
return __rdtscp(a);
22+
23+
// CIR-LABEL: @__rdtscp
24+
// CIR: [[RDTSCP:%.*]] = cir.llvm.intrinsic "x86.rdtscp" : () -> !rec_anon_struct
25+
// CIR: [[TSC_AUX:%.*]] = cir.extract_member [[RDTSCP]][1] : !rec_anon_struct -> !u32i
26+
// CIR: cir.store [[TSC_AUX]], %{{.*}} : !u32i, !cir.ptr<!u32i>
27+
// CIR: {{%.*}} = cir.extract_member [[RDTSCP]][0] : !rec_anon_struct -> !u64i
28+
29+
// LLVM: @test_rdtscp
30+
// LLVM: [[RDTSCP:%.*]] = call { i64, i32 } @llvm.x86.rdtscp
31+
// LLVM: [[TSC_AUX:%.*]] = extractvalue { i64, i32 } [[RDTSCP]], 1
32+
// LLVM: store i32 [[TSC_AUX]], ptr %{{.*}}
33+
// LLVM: [[TSC:%.*]] = extractvalue { i64, i32 } [[RDTSCP]], 0
34+
}
35+

0 commit comments

Comments
 (0)