@@ -532,13 +532,17 @@ decodeFixedType(ArrayRef<llvm::Intrinsic::IITDescriptor> &infos,
532532}
533533
534534// llvm::Intrinsics accepts only LLVMContext. We need to reimplement it here.
535- // Takes AST information to infer correct signedness when
536- // IIT returns signed but AST shows unsigned in Function Decl (indicating
537- // intrinsic expects unsigned)
538- static cir::FuncType getIntrinsicType (mlir::MLIRContext *context,
539- llvm::Intrinsic::ID id,
540- const CallExpr *E) {
541- using namespace llvm ::Intrinsic;
535+ // / Helper function to correct integer signedness for intrinsic arguments.
536+ // / IIT always returns signed integers, but the actual intrinsic may expect
537+ // / unsigned integers based on the AST FunctionDecl parameter types.
538+ static mlir::Type
539+ correctIntrinsicIntegerSignedness (mlir::Type iitType, const CallExpr *E,
540+ unsigned argIndex,
541+ mlir::MLIRContext *context) {
542+ // If it's not an integer type, return as-is
543+ auto intTy = dyn_cast<cir::IntType>(iitType);
544+ if (!intTy)
545+ return iitType;
542546
543547 // Get the FunctionDecl from the CallExpr
544548 const FunctionDecl *FD = nullptr ;
@@ -547,40 +551,32 @@ static cir::FuncType getIntrinsicType(mlir::MLIRContext *context,
547551 FD = dyn_cast<FunctionDecl>(DRE->getDecl ());
548552 }
549553
554+ // If we have FunctionDecl and this argument exists, check its signedness
555+ if (FD && argIndex < FD->getNumParams ()) {
556+ QualType paramType = FD->getParamDecl (argIndex)->getType ();
557+ if (paramType->isUnsignedIntegerType ()) {
558+ // Create unsigned version of the type
559+ return IntType::get (context, intTy.getWidth (), /* isSigned=*/ false );
560+ }
561+ }
562+
563+ // Default: keep IIT type (signed)
564+ return iitType;
565+ }
566+
567+ static cir::FuncType getIntrinsicType (mlir::MLIRContext *context,
568+ llvm::Intrinsic::ID id) {
569+ using namespace llvm ::Intrinsic;
570+
550571 SmallVector<IITDescriptor, 8 > table;
551572 getIntrinsicInfoTableEntries (id, table);
552573
553574 ArrayRef<IITDescriptor> tableRef = table;
554575 mlir::Type resultTy = decodeFixedType (tableRef, context);
555576
556- // Use FunctionDecl return type if available
557- if (auto intTy = dyn_cast<cir::IntType>(resultTy)) {
558- if (FD && FD->getReturnType ()->isUnsignedIntegerType ()) {
559- resultTy = IntType::get (context, intTy.getWidth (), /* signed=*/ false );
560- }
561- // Otherwise keep IIT default (signed)
562- }
563-
564577 SmallVector<mlir::Type, 8 > argTypes;
565- unsigned argIndex = 0 ;
566578 while (!tableRef.empty ()) {
567- mlir::Type argTy = decodeFixedType (tableRef, context);
568-
569- // Adjust argument type signedness based on FunctionDecl parameter
570- // definition
571- if (auto intTy = dyn_cast<cir::IntType>(argTy)) {
572- if (FD && argIndex < FD->getNumParams ()) {
573- QualType paramType = FD->getParamDecl (argIndex)->getType ();
574- if (paramType->isUnsignedIntegerType ()) {
575- argTy = IntType::get (context, intTy.getWidth (), /* signed=*/ false );
576- }
577- // Otherwise keep IIT default (signed)
578- }
579- // If no FunctionDecl, keep IIT default (signed)
580- }
581-
582- argTypes.push_back (argTy);
583- argIndex++;
579+ argTypes.push_back (decodeFixedType (tableRef, context));
584580 }
585581
586582 return FuncType::get (argTypes, resultTy);
@@ -2763,7 +2759,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27632759 assert (false && " bad intrinsic name!" );
27642760
27652761 cir::FuncType intrinsicType =
2766- getIntrinsicType (&getMLIRContext (), intrinsicID, E );
2762+ getIntrinsicType (&getMLIRContext (), intrinsicID);
27672763
27682764 SmallVector<mlir::Value> args;
27692765 for (unsigned i = 0 ; i < E->getNumArgs (); i++) {
@@ -2772,10 +2768,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27722768 // we need to do a bit cast.
27732769 mlir::Type argType = argValue.getType ();
27742770 mlir::Type expectedTy = intrinsicType.getInput (i);
2775- if (argType != expectedTy) {
2771+
2772+ // Use helper to get the correct integer type based on AST signedness
2773+ mlir::Type correctedExpectedTy = correctIntrinsicIntegerSignedness (
2774+ expectedTy, E, i, &getMLIRContext ());
2775+
2776+ if (argType != correctedExpectedTy) {
27762777 // XXX - vector of pointers?
27772778 if (cir::PointerType expectedPtrTy =
2778- dyn_cast<cir::PointerType>(expectedTy )) {
2779+ dyn_cast<cir::PointerType>(correctedExpectedTy )) {
27792780 if (cir::PointerType argPtrTy = dyn_cast<cir::PointerType>(argType)) {
27802781 if (expectedPtrTy.getAddrSpace () != argPtrTy.getAddrSpace ()) {
27812782 argValue = builder.createAddrSpaceCast (
@@ -2787,7 +2788,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27872788 }
27882789 // TODO(cir): Cast vector type (e.g., v256i32) to x86_amx, this only
27892790 // happens in amx intrinsics.
2790- argValue = builder.createBitcast (argValue, expectedTy);
2791+ if (cir::MissingFeatures::vectorToX86AmxCasting ()) {
2792+ llvm_unreachable (" NYI" );
2793+ }
2794+
2795+ argValue = builder.createBitcast (argValue, correctedExpectedTy);
27912796 }
27922797
27932798 args.push_back (argValue);
0 commit comments