https://github.com/Priyanshu3820 updated https://github.com/llvm/llvm-project/pull/179098
>From 920033dae1b1ab9ecb420b3d869a7eade300f87f Mon Sep 17 00:00:00 2001 From: Priyanshu <[email protected]> Date: Sun, 1 Feb 2026 15:38:02 +0530 Subject: [PATCH 1/3] Upstream generic intrinsic emission path --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 200 ++++++++++++++++++ .../CIR/CodeGenBuiltins/X86/rd-builtins.c | 25 +++ 2 files changed, 225 insertions(+) create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 0e5a5b531df78..3f5cb6e440591 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -26,6 +26,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/CIR/Dialect/IR/CIRTypes.h" #include "clang/CIR/MissingFeatures.h" +#include "llvm/IR/Intrinsics.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -726,6 +727,108 @@ static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, const CallExpr *e, return RValue::getIgnored(); } +static mlir::Type +decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos, + mlir::MLIRContext *context) { + using namespace llvm::Intrinsic; + + IITDescriptor descriptor = infos.front(); + infos = infos.slice(1); + + switch (descriptor.Kind) { + case IITDescriptor::Void: + return cir::VoidType::get(context); + case IITDescriptor::Integer: + return cir::IntType::get(context, descriptor.Integer_Width, + /*isSigned=*/true); + case IITDescriptor::Float: + return cir::SingleType::get(context); + case IITDescriptor::Double: + return cir::DoubleType::get(context); + default: + llvm_unreachable("NYI"); + } +} + +/// Helper function to correct integer signedness for intrinsic arguments. +/// IIT always returns signed integers, but the actual intrinsic may expect +/// unsigned integers based on the AST FunctionDecl parameter types. +static mlir::Type getIntrinsicArgumentTypeFromAST(mlir::Type iitType, + const CallExpr *E, + unsigned argIndex, + mlir::MLIRContext *context) { + // If it's not an integer type, return as-is + auto intTy = dyn_cast<cir::IntType>(iitType); + if (!intTy) + return iitType; + + // Get the FunctionDecl from the CallExpr + const FunctionDecl *FD = nullptr; + if (const auto *DRE = + dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImpCasts())) { + FD = dyn_cast<FunctionDecl>(DRE->getDecl()); + } + + // If we have FunctionDecl and this argument exists, check its signedness + if (FD && argIndex < FD->getNumParams()) { + QualType paramType = FD->getParamDecl(argIndex)->getType(); + if (paramType->isUnsignedIntegerType()) { + // Create unsigned version of the type + return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false); + } + } + + // Default: keep IIT type (signed) + return iitType; +} + +static mlir::Value getCorrectedPtr(mlir::Value argValue, mlir::Type expectedTy, + CIRGenBuilderTy &builder) { + auto ptrType = mlir::dyn_cast<cir::PointerType>(argValue.getType()); + assert(ptrType && "expected pointer type"); + + auto expectedPtrType = mlir::cast<cir::PointerType>(expectedTy); + assert(ptrType.getPointee() != expectedPtrType.getPointee() && + "types should not match"); + + if (ptrType.getAddrSpace() != expectedPtrType.getAddrSpace()) { + auto newPtrType = cir::PointerType::get(ptrType.getPointee(), + expectedPtrType.getAddrSpace()); + return builder.createAddrSpaceCast(argValue, newPtrType); + } + + return argValue; +} + +static cir::FuncType getIntrinsicType(mlir::MLIRContext *context, + llvm::Intrinsic::ID id) { + using namespace llvm::Intrinsic; + + SmallVector<IITDescriptor, 8> table; + getIntrinsicInfoTableEntries(id, table); + + ArrayRef<IITDescriptor> tableRef = table; + mlir::Type resultTy = decodeFixedType(tableRef, context); + + SmallVector<mlir::Type, 8> argTypes; + bool isVarArg = false; + while (!tableRef.empty()) { + auto kind = tableRef.front().Kind; + if (kind == IITDescriptor::VarArg) { + isVarArg = true; + break; // VarArg is last + } + argTypes.push_back(decodeFixedType(tableRef, context)); + } + + // CIR convention: no explicit void return type + if (isa<cir::VoidType>(resultTy)) + return cir::FuncType::get(context, argTypes, /*optionalReturnType=*/nullptr, + isVarArg); + + return cir::FuncType::get(context, argTypes, resultTy, isVarArg); +} + RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, const CallExpr *e, ReturnValueSlot returnValue) { @@ -1798,6 +1901,103 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, return emitLibraryCall(*this, fd, e, cgm.getBuiltinLibFunction(fd, builtinID)); + // See if we have a target specific intrinsic. + std::string name = getContext().BuiltinInfo.getName(builtinID); + Intrinsic::ID intrinsicID = Intrinsic::not_intrinsic; + StringRef prefix = + llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); + if (!prefix.empty()) { + intrinsicID = Intrinsic::getIntrinsicForClangBuiltin(prefix.data(), name); + // NOTE we don't need to perform a compatibility flag check here since the + // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the + // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. + if (intrinsicID == Intrinsic::not_intrinsic) + intrinsicID = Intrinsic::getIntrinsicForMSBuiltin(prefix.data(), name); + } + + if (intrinsicID != Intrinsic::not_intrinsic) { + unsigned iceArguments = 0; + ASTContext::GetBuiltinTypeError error; + getContext().GetBuiltinType(builtinID, error, &iceArguments); + assert(error == ASTContext::GE_None && "Should not codegen an error"); + + llvm::StringRef name = llvm::Intrinsic::getName(intrinsicID); + // cir::LLVMIntrinsicCallOp expects intrinsic name to not have prefix + // "llvm." For example, `llvm.nvvm.barrier0` should be passed as + // `nvvm.barrier0`. + if (!name.consume_front("llvm.")) + assert(false && "bad intrinsic name!"); + + cir::FuncType intrinsicType = + getIntrinsicType(&getMLIRContext(), intrinsicID); + + SmallVector<mlir::Value> args; + for (unsigned i = 0; i < e->getNumArgs(); i++) { + mlir::Value argValue = + emitScalarOrConstFoldImmArg(iceArguments, i, e->getArg(i)); + // If the intrinsic arg type is different from the builtin arg type + // we need to do a bit cast. + mlir::Type argType = argValue.getType(); + mlir::Type expectedTy = intrinsicType.getInput(i); + + // Use helper to get the correct integer type based on AST signedness + mlir::Type correctedExpectedTy = + getIntrinsicArgumentTypeFromAST(expectedTy, e, i, &getMLIRContext()); + + if (argType != correctedExpectedTy) + argValue = getCorrectedPtr(argValue, expectedTy, builder); + + args.push_back(argValue); + } + + cir::LLVMIntrinsicCallOp intrinsicCall = cir::LLVMIntrinsicCallOp::create( + builder, getLoc(e->getExprLoc()), builder.getStringAttr(name), + intrinsicType.getReturnType(), args); + + // Convert the intrinsic result to the CallExpr/AST expected return type if + // they differ. This can happen when an intrinsic's IIT uses a signed + // integer type while the AST declares an unsigned type, or when an + // intrinsic returns an integer but the AST expects a pointer (or vice + // versa). Coerce conservatively so subsequent stores/verifications succeed. + mlir::Value intrinsicRes = intrinsicCall.getResult(); + mlir::Type builtinReturnType = intrinsicRes.getType(); + mlir::Type expectedRetTy = convertType(e->getType()); + + if (builtinReturnType != expectedRetTy) { + // Integer -> Integer or width/signage differences. + if (cir::IntType fromInt = + mlir::dyn_cast<cir::IntType>(builtinReturnType)) { + if (cir::IntType toInt = mlir::dyn_cast<cir::IntType>(expectedRetTy)) + intrinsicRes = builder.createIntCast(intrinsicRes, expectedRetTy); + else if (mlir::dyn_cast<cir::PointerType>(expectedRetTy)) + intrinsicRes = builder.createIntToPtr(intrinsicRes, expectedRetTy); + else + intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); + + } else if (cir::PointerType fromPtr = + mlir::dyn_cast<cir::PointerType>(builtinReturnType)) { + if (mlir::dyn_cast<cir::IntType>(expectedRetTy)) + intrinsicRes = builder.createPtrToInt(intrinsicRes, expectedRetTy); + else if (cir::PointerType toPtr = + mlir::dyn_cast<cir::PointerType>(expectedRetTy)) { + if (fromPtr.getAddrSpace() != toPtr.getAddrSpace()) + intrinsicRes = + builder.createAddrSpaceCast(intrinsicRes, expectedRetTy); + else if (fromPtr.getPointee() != toPtr.getPointee()) + intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); + } else + intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); + + } else + intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); + } + + if (isa<cir::VoidType>(expectedRetTy)) + return RValue::get(nullptr); + + return RValue::get(intrinsicRes); + } + // Some target-specific builtins can have aggregate return values, e.g. // __builtin_arm_mve_vld2q_u32. So if the result is an aggregate, force // returnValue to be non-null, so that the target-specific emission code can diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c new file mode 100644 index 0000000000000..a1ac394110e39 --- /dev/null +++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c @@ -0,0 +1,25 @@ +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s +// RUN: %clang -target x86_64-unknown-linux-gnu -S -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s + +#include <x86intrin.h> + +unsigned long long test_rdpmc(int a) { + // CIR-LABEL: test_rdpmc + // CIR: cir.call @__rdpmc + // CIR: cir.store %{{.*}}, %{{.*}} : !u64i, !cir.ptr<!u64i> + // CIR: cir.return %{{.*}} : !u64i + + // LLVM-LABEL: @test_rdpmc + // LLVM: call i64 @llvm.x86.rdpmc + // LLVM: store i64 %{{.*}}, ptr %{{.*}}, align 8 + // LLVM: ret i64 %{{.*}} + + // OGCG-LABEL: @test_rdpmc + // OGCG: call i64 @llvm.x86.rdpmc + // OGCG: ret i64 %{{.*}} + return _rdpmc(a); +} >From 2364a138f0d81d2b77e634ab3377ccbe7391b3fe Mon Sep 17 00:00:00 2001 From: Priyanshu <[email protected]> Date: Sun, 1 Feb 2026 22:33:03 +0530 Subject: [PATCH 2/3] Update test --- clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c index a1ac394110e39..a66302c50cec5 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c @@ -1,12 +1,16 @@ -// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir // RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s -// RUN: %clang -target x86_64-unknown-linux-gnu -fclangir -S -emit-llvm %s -o %t-cir.ll +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s -// RUN: %clang -target x86_64-unknown-linux-gnu -S -emit-llvm %s -o %t.ll +// RUN: %clang_cc1 -ffreestanding -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s #include <x86intrin.h> +// CIR-LABEL: @__rdpmc +// CIR: cir.call_llvm_intrinsic "x86.rdpmc" +// CIR: cir.cast integral %{{.*}} : !s64i -> !u64i + unsigned long long test_rdpmc(int a) { // CIR-LABEL: test_rdpmc // CIR: cir.call @__rdpmc >From 1f519a7f68965474688a2d7c5fc920448caff7a8 Mon Sep 17 00:00:00 2001 From: Priyanshu <[email protected]> Date: Tue, 3 Feb 2026 19:26:22 +0530 Subject: [PATCH 3/3] Adress reviews and update test --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 122 +++++++----------- .../CIR/CodeGenBuiltins/X86/rd-builtins.c | 3 +- 2 files changed, 47 insertions(+), 78 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 3f5cb6e440591..ebd3cee020bf8 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -727,8 +727,10 @@ static RValue tryEmitFPMathIntrinsic(CIRGenFunction &cgf, const CallExpr *e, return RValue::getIgnored(); } +// FIXME: Remove cgf parameter when all descriptor kinds are implemented static mlir::Type -decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos, +decodeFixedType(CIRGenFunction &cgf, + ArrayRef<llvm::Intrinsic::IITDescriptor> &infos, mlir::MLIRContext *context) { using namespace llvm::Intrinsic; @@ -738,6 +740,8 @@ decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos, switch (descriptor.Kind) { case IITDescriptor::Void: return cir::VoidType::get(context); + // If the intrinsic expects unsigned integers, the signedness is corrected in + // correctIntegerSignedness() case IITDescriptor::Integer: return cir::IntType::get(context, descriptor.Integer_Width, /*isSigned=*/true); @@ -746,39 +750,23 @@ decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos, case IITDescriptor::Double: return cir::DoubleType::get(context); default: - llvm_unreachable("NYI"); + cgf.cgm.errorNYI("Unimplemented intrinsic type descriptor"); + return cir::VoidType::get(context); } } -/// Helper function to correct integer signedness for intrinsic arguments. -/// IIT always returns signed integers, but the actual intrinsic may expect -/// unsigned integers based on the AST FunctionDecl parameter types. -static mlir::Type getIntrinsicArgumentTypeFromAST(mlir::Type iitType, - const CallExpr *E, - unsigned argIndex, - mlir::MLIRContext *context) { - // If it's not an integer type, return as-is +/// Helper function to correct integer signedness for intrinsic arguments and +/// return type. IIT always returns signed integers, but the actual intrinsic +/// may expect unsigned integers based on the AST FunctionDecl parameter types. +static mlir::Type correctIntegerSignedness(mlir::Type iitType, QualType astType, + mlir::MLIRContext *context) { auto intTy = dyn_cast<cir::IntType>(iitType); if (!intTy) return iitType; - // Get the FunctionDecl from the CallExpr - const FunctionDecl *FD = nullptr; - if (const auto *DRE = - dyn_cast<DeclRefExpr>(E->getCallee()->IgnoreImpCasts())) { - FD = dyn_cast<FunctionDecl>(DRE->getDecl()); - } - - // If we have FunctionDecl and this argument exists, check its signedness - if (FD && argIndex < FD->getNumParams()) { - QualType paramType = FD->getParamDecl(argIndex)->getType(); - if (paramType->isUnsignedIntegerType()) { - // Create unsigned version of the type - return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false); - } + if (astType->isUnsignedIntegerType()) { + return cir::IntType::get(context, intTy.getWidth(), /*isSigned=*/false); } - - // Default: keep IIT type (signed) return iitType; } @@ -788,8 +776,7 @@ static mlir::Value getCorrectedPtr(mlir::Value argValue, mlir::Type expectedTy, assert(ptrType && "expected pointer type"); auto expectedPtrType = mlir::cast<cir::PointerType>(expectedTy); - assert(ptrType.getPointee() != expectedPtrType.getPointee() && - "types should not match"); + assert(ptrType != expectedPtrType && "types should not match"); if (ptrType.getAddrSpace() != expectedPtrType.getAddrSpace()) { auto newPtrType = cir::PointerType::get(ptrType.getPointee(), @@ -797,10 +784,11 @@ static mlir::Value getCorrectedPtr(mlir::Value argValue, mlir::Type expectedTy, return builder.createAddrSpaceCast(argValue, newPtrType); } - return argValue; + return builder.createBitcast(argValue, expectedTy); } -static cir::FuncType getIntrinsicType(mlir::MLIRContext *context, +static cir::FuncType getIntrinsicType(CIRGenFunction &cgf, + mlir::MLIRContext *context, llvm::Intrinsic::ID id) { using namespace llvm::Intrinsic; @@ -808,17 +796,18 @@ static cir::FuncType getIntrinsicType(mlir::MLIRContext *context, getIntrinsicInfoTableEntries(id, table); ArrayRef<IITDescriptor> tableRef = table; - mlir::Type resultTy = decodeFixedType(tableRef, context); + mlir::Type resultTy = decodeFixedType(cgf, tableRef, context); SmallVector<mlir::Type, 8> argTypes; bool isVarArg = false; while (!tableRef.empty()) { - auto kind = tableRef.front().Kind; + llvm::Intrinsic::IITDescriptor::IITDescriptorKind kind = + tableRef.front().Kind; if (kind == IITDescriptor::VarArg) { isVarArg = true; break; // VarArg is last } - argTypes.push_back(decodeFixedType(tableRef, context)); + argTypes.push_back(decodeFixedType(cgf, tableRef, context)); } // CIR convention: no explicit void return type @@ -836,8 +825,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, // See if we can constant fold this builtin. If so, don't emit it at all. // TODO: Extend this handling to all builtin calls that we can constant-fold. + // Do not constant-fold immediate (target-specific) builtins; their ASTs can + // trigger the constant evaluator in cases it cannot safely handle. + // Skip EvaluateAsRValue for those. Expr::EvalResult result; - if (e->isPRValue() && e->EvaluateAsRValue(result, cgm.getASTContext()) && + if (e->isPRValue() && !getContext().BuiltinInfo.isImmediate(builtinID) && + e->EvaluateAsRValue(result, cgm.getASTContext()) && !result.hasSideEffects()) { if (result.Val.isInt()) return RValue::get(builder.getConstInt(loc, result.Val.getInt())); @@ -1929,9 +1922,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, assert(false && "bad intrinsic name!"); cir::FuncType intrinsicType = - getIntrinsicType(&getMLIRContext(), intrinsicID); + getIntrinsicType(*this, &getMLIRContext(), intrinsicID); SmallVector<mlir::Value> args; + const FunctionDecl *fd = e->getDirectCallee(); for (unsigned i = 0; i < e->getNumArgs(); i++) { mlir::Value argValue = emitScalarOrConstFoldImmArg(iceArguments, i, e->getArg(i)); @@ -1940,9 +1934,12 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, mlir::Type argType = argValue.getType(); mlir::Type expectedTy = intrinsicType.getInput(i); - // Use helper to get the correct integer type based on AST signedness - mlir::Type correctedExpectedTy = - getIntrinsicArgumentTypeFromAST(expectedTy, e, i, &getMLIRContext()); + // Correct integer signedness based on AST parameter type + mlir::Type correctedExpectedTy = expectedTy; + if (fd && i < fd->getNumParams()) { + correctedExpectedTy = correctIntegerSignedness( + expectedTy, fd->getParamDecl(i)->getType(), &getMLIRContext()); + } if (argType != correctedExpectedTy) argValue = getCorrectedPtr(argValue, expectedTy, builder); @@ -1950,49 +1947,22 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, args.push_back(argValue); } + // Correct return type signedness based on AST return type before creating + // the call, avoiding unnecessary casts in the IR. + mlir::Type correctedReturnType = intrinsicType.getReturnType(); + if (fd) { + correctedReturnType = + correctIntegerSignedness(intrinsicType.getReturnType(), + fd->getReturnType(), &getMLIRContext()); + } + cir::LLVMIntrinsicCallOp intrinsicCall = cir::LLVMIntrinsicCallOp::create( builder, getLoc(e->getExprLoc()), builder.getStringAttr(name), - intrinsicType.getReturnType(), args); + correctedReturnType, args); - // Convert the intrinsic result to the CallExpr/AST expected return type if - // they differ. This can happen when an intrinsic's IIT uses a signed - // integer type while the AST declares an unsigned type, or when an - // intrinsic returns an integer but the AST expects a pointer (or vice - // versa). Coerce conservatively so subsequent stores/verifications succeed. mlir::Value intrinsicRes = intrinsicCall.getResult(); - mlir::Type builtinReturnType = intrinsicRes.getType(); - mlir::Type expectedRetTy = convertType(e->getType()); - - if (builtinReturnType != expectedRetTy) { - // Integer -> Integer or width/signage differences. - if (cir::IntType fromInt = - mlir::dyn_cast<cir::IntType>(builtinReturnType)) { - if (cir::IntType toInt = mlir::dyn_cast<cir::IntType>(expectedRetTy)) - intrinsicRes = builder.createIntCast(intrinsicRes, expectedRetTy); - else if (mlir::dyn_cast<cir::PointerType>(expectedRetTy)) - intrinsicRes = builder.createIntToPtr(intrinsicRes, expectedRetTy); - else - intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); - - } else if (cir::PointerType fromPtr = - mlir::dyn_cast<cir::PointerType>(builtinReturnType)) { - if (mlir::dyn_cast<cir::IntType>(expectedRetTy)) - intrinsicRes = builder.createPtrToInt(intrinsicRes, expectedRetTy); - else if (cir::PointerType toPtr = - mlir::dyn_cast<cir::PointerType>(expectedRetTy)) { - if (fromPtr.getAddrSpace() != toPtr.getAddrSpace()) - intrinsicRes = - builder.createAddrSpaceCast(intrinsicRes, expectedRetTy); - else if (fromPtr.getPointee() != toPtr.getPointee()) - intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); - } else - intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); - - } else - intrinsicRes = builder.createBitcast(intrinsicRes, expectedRetTy); - } - if (isa<cir::VoidType>(expectedRetTy)) + if (isa<cir::VoidType>(correctedReturnType)) return RValue::get(nullptr); return RValue::get(intrinsicRes); diff --git a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c index a66302c50cec5..28d4d6f06ddd1 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/rd-builtins.c @@ -8,8 +8,7 @@ #include <x86intrin.h> // CIR-LABEL: @__rdpmc -// CIR: cir.call_llvm_intrinsic "x86.rdpmc" -// CIR: cir.cast integral %{{.*}} : !s64i -> !u64i +// CIR: cir.call_llvm_intrinsic "x86.rdpmc" %{{.*}} : (!s32i) -> !u64i unsigned long long test_rdpmc(int a) { // CIR-LABEL: test_rdpmc _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
