Skip to content

Commit 6e489c8

Browse files
committed
Decouple IIT Signedness resolution from getIntrinsicType
1 parent 121909e commit 6e489c8

File tree

2 files changed

+44
-39
lines changed

2 files changed

+44
-39
lines changed

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct MissingFeatures {
7474
// GNU vectors are done, but other kinds of vectors haven't been implemented.
7575
static bool scalableVectors() { return false; }
7676
static bool vectorConstants() { return false; }
77+
static bool vectorToX86AmxCasting() { return false; }
7778

7879
// Address space related
7980
static bool addressSpace() { return false; }

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)