[CIR] Support x86 builtin rdtsc (#180714)
This PR implements CodeGen for rdtsc builtins in CIR upstream. Towards #167765
This commit is contained in:
parent
4aa5573b14
commit
49fa2a4d24
@ -860,11 +860,24 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
|
||||
case X86::BI_m_prefetchw:
|
||||
return emitPrefetch(*this, builtinID, expr, ops);
|
||||
case X86::BI__rdtsc:
|
||||
return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), "x86.rdtsc",
|
||||
builder.getUInt64Ty());
|
||||
case X86::BI__builtin_ia32_rdtscp: {
|
||||
cgm.errorNYI(expr->getSourceRange(),
|
||||
std::string("unimplemented X86 builtin call: ") +
|
||||
getContext().BuiltinInfo.getName(builtinID));
|
||||
return mlir::Value{};
|
||||
mlir::Location loc = getLoc(expr->getExprLoc());
|
||||
mlir::Type i64Ty = builder.getUInt64Ty();
|
||||
mlir::Type i32Ty = builder.getUInt32Ty();
|
||||
mlir::Type structTy = builder.getAnonRecordTy({i64Ty, i32Ty});
|
||||
mlir::Value result =
|
||||
builder.emitIntrinsicCallOp(loc, "x86.rdtscp", structTy);
|
||||
|
||||
// Extract and store processor_id (element 1 of the returned struct)
|
||||
mlir::Value processorId =
|
||||
cir::ExtractMemberOp::create(builder, loc, i32Ty, result, 1);
|
||||
// ops[0] is the address to store the processor ID
|
||||
builder.createStore(loc, processorId, Address{ops[0], CharUnits::One()});
|
||||
|
||||
// Return timestamp (element 0 of the returned struct)
|
||||
return cir::ExtractMemberOp::create(builder, loc, i64Ty, result, 0);
|
||||
}
|
||||
case X86::BI__builtin_ia32_lzcnt_u16:
|
||||
case X86::BI__builtin_ia32_lzcnt_u32:
|
||||
|
||||
@ -26,3 +26,39 @@ unsigned long long test_rdpmc(int a) {
|
||||
// OGCG: ret i64 %{{.*}}
|
||||
return _rdpmc(a);
|
||||
}
|
||||
|
||||
unsigned long long test_rdtsc(void) {
|
||||
// CIR-LABEL: @test_rdtsc
|
||||
// CIR: %{{.*}} = cir.call_llvm_intrinsic "x86.rdtsc" : () -> !u64i
|
||||
|
||||
// LLVM-LABEL: @test_rdtsc
|
||||
// LLVM: call i64 @llvm.x86.rdtsc()
|
||||
|
||||
// OGCG-LABEL: @test_rdtsc
|
||||
// OGCG: call i64 @llvm.x86.rdtsc()
|
||||
|
||||
return __rdtsc();
|
||||
}
|
||||
|
||||
unsigned long long test_rdtscp(unsigned int *a) {
|
||||
// CIR-LABEL: @test_rdtscp
|
||||
// CIR: %[[RDTSCP:.*]] = cir.call_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: %[[TSC:.*]] = cir.extract_member %[[RDTSCP]][0] : !rec_anon_struct -> !u64i
|
||||
|
||||
// LLVM-LABEL: @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
|
||||
|
||||
// OGCG-LABEL: @test_rdtscp
|
||||
// OGCG: %[[RDTSCP:.*]] = call { i64, i32 } @llvm.x86.rdtscp
|
||||
// OGCG: %[[TSC_AUX:.*]] = extractvalue { i64, i32 } %[[RDTSCP]], 1
|
||||
// OGCG: store i32 %[[TSC_AUX]], ptr %{{.*}}
|
||||
// OGCG: %[[TSC:.*]] = extractvalue { i64, i32 } %[[RDTSCP]], 0
|
||||
|
||||
return __builtin_ia32_rdtscp(a);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user