@@ -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,41 +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 ;
566- 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++;
584- }
578+ while (!tableRef.empty ())
579+ argTypes.push_back (decodeFixedType (tableRef, context));
585580
586581 return FuncType::get (argTypes, resultTy);
587582}
@@ -2763,7 +2758,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27632758 assert (false && " bad intrinsic name!" );
27642759
27652760 cir::FuncType intrinsicType =
2766- getIntrinsicType (&getMLIRContext (), intrinsicID, E );
2761+ getIntrinsicType (&getMLIRContext (), intrinsicID);
27672762
27682763 SmallVector<mlir::Value> args;
27692764 for (unsigned i = 0 ; i < E->getNumArgs (); i++) {
@@ -2772,10 +2767,15 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27722767 // we need to do a bit cast.
27732768 mlir::Type argType = argValue.getType ();
27742769 mlir::Type expectedTy = intrinsicType.getInput (i);
2775- if (argType != expectedTy) {
2770+
2771+ // Use helper to get the correct integer type based on AST signedness
2772+ mlir::Type correctedExpectedTy = correctIntrinsicIntegerSignedness (
2773+ expectedTy, E, i, &getMLIRContext ());
2774+
2775+ if (argType != correctedExpectedTy) {
27762776 // XXX - vector of pointers?
27772777 if (cir::PointerType expectedPtrTy =
2778- dyn_cast<cir::PointerType>(expectedTy )) {
2778+ dyn_cast<cir::PointerType>(correctedExpectedTy )) {
27792779 if (cir::PointerType argPtrTy = dyn_cast<cir::PointerType>(argType)) {
27802780 if (expectedPtrTy.getAddrSpace () != argPtrTy.getAddrSpace ()) {
27812781 argValue = builder.createAddrSpaceCast (
@@ -2787,7 +2787,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
27872787 }
27882788 // TODO(cir): Cast vector type (e.g., v256i32) to x86_amx, this only
27892789 // happens in amx intrinsics.
2790- argValue = builder.createBitcast (argValue, expectedTy);
2790+ if (cir::MissingFeatures::vectorToX86AmxCasting ()) {
2791+ llvm_unreachable (" NYI" );
2792+ }
2793+
2794+ argValue = builder.createBitcast (argValue, correctedExpectedTy);
27912795 }
27922796
27932797 args.push_back (argValue);
0 commit comments