diff options
Diffstat (limited to 'clang/lib/CIR')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenBuilder.h | 30 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 55 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 20 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp | 32 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 11 | ||||
-rw-r--r-- | clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 10 |
13 files changed, 149 insertions, 67 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 73c9fb9..ff8e121 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -410,21 +410,37 @@ public: mlir::Value createSetBitfield(mlir::Location loc, mlir::Type resultType, Address dstAddr, mlir::Type storageType, mlir::Value src, const CIRGenBitFieldInfo &info, - bool isLvalueVolatile) { + bool isLvalueVolatile, bool useVolatile) { + unsigned offset = useVolatile ? info.volatileOffset : info.offset; + + // If using AAPCS and the field is volatile, load with the size of the + // declared field + storageType = + useVolatile ? cir::IntType::get(storageType.getContext(), + info.volatileStorageSize, info.isSigned) + : storageType; return create<cir::SetBitfieldOp>( loc, resultType, dstAddr.getPointer(), storageType, src, info.name, - info.size, info.offset, info.isSigned, isLvalueVolatile, + info.size, offset, info.isSigned, isLvalueVolatile, dstAddr.getAlignment().getAsAlign().value()); } mlir::Value createGetBitfield(mlir::Location loc, mlir::Type resultType, Address addr, mlir::Type storageType, const CIRGenBitFieldInfo &info, - bool isLvalueVolatile) { - return create<cir::GetBitfieldOp>( - loc, resultType, addr.getPointer(), storageType, info.name, info.size, - info.offset, info.isSigned, isLvalueVolatile, - addr.getAlignment().getAsAlign().value()); + bool isLvalueVolatile, bool useVolatile) { + unsigned offset = useVolatile ? info.volatileOffset : info.offset; + + // If using AAPCS and the field is volatile, load with the size of the + // declared field + storageType = + useVolatile ? cir::IntType::get(storageType.getContext(), + info.volatileStorageSize, info.isSigned) + : storageType; + return create<cir::GetBitfieldOp>(loc, resultType, addr.getPointer(), + storageType, info.name, info.size, offset, + info.isSigned, isLvalueVolatile, + addr.getAlignment().getAsAlign().value()); } }; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 9049a01..7767bf4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -21,6 +21,7 @@ #include "mlir/Support/LLVM.h" #include "clang/AST/Expr.h" #include "clang/AST/GlobalDecl.h" +#include "clang/Basic/Builtins.h" #include "clang/CIR/MissingFeatures.h" #include "llvm/Support/ErrorHandling.h" @@ -269,6 +270,14 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, case Builtin::BI__builtin_rotateright32: case Builtin::BI__builtin_rotateright64: return emitRotate(e, /*isRotateLeft=*/false); + + case Builtin::BI__builtin_trap: + emitTrap(loc, /*createNewBlock=*/true); + return RValue::get(nullptr); + + case Builtin::BI__builtin_unreachable: + emitUnreachable(e->getExprLoc(), /*createNewBlock=*/true); + return RValue::get(nullptr); } // If this is an alias for a lib function (e.g. __builtin_sin), emit diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 9cdbebe..78d375c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -158,7 +158,7 @@ void CIRGenFunction::emitAutoVarInit( // out of it while trying to build the expression, mark it as such. mlir::Value val = lv.getAddress().getPointer(); assert(val && "Should have an address"); - auto allocaOp = dyn_cast_or_null<cir::AllocaOp>(val.getDefiningOp()); + auto allocaOp = val.getDefiningOp<cir::AllocaOp>(); assert(allocaOp && "Address should come straight out of the alloca"); if (!allocaOp.use_empty()) @@ -412,7 +412,8 @@ void CIRGenFunction::emitStaticVarDecl(const VarDecl &d, // TODO(cir): we should have a way to represent global ops as values without // having to emit a get global op. Sometimes these emissions are not used. mlir::Value addr = builder.createGetGlobal(globalOp); - auto getAddrOp = mlir::cast<cir::GetGlobalOp>(addr.getDefiningOp()); + auto getAddrOp = addr.getDefiningOp<cir::GetGlobalOp>(); + assert(getAddrOp && "expected cir::GetGlobalOp"); CharUnits alignment = getContext().getDeclAlign(&d); diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 761d8d3..a0ff08e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -303,8 +303,7 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr, // Update the alloca with more info on initialization. assert(addr.getPointer() && "expected pointer to exist"); - auto srcAlloca = - dyn_cast_or_null<cir::AllocaOp>(addr.getPointer().getDefiningOp()); + auto srcAlloca = addr.getDefiningOp<cir::AllocaOp>(); if (currVarDecl && srcAlloca) { const VarDecl *vd = currVarDecl; assert(vd && "VarDecl expected"); @@ -323,22 +322,28 @@ void CIRGenFunction::emitStoreOfScalar(mlir::Value value, Address addr, assert(!cir::MissingFeatures::opTBAA()); } +// TODO: Replace this with a proper TargetInfo function call. +/// Helper method to check if the underlying ABI is AAPCS +static bool isAAPCS(const TargetInfo &targetInfo) { + return targetInfo.getABI().starts_with("aapcs"); +} + mlir::Value CIRGenFunction::emitStoreThroughBitfieldLValue(RValue src, LValue dst) { - assert(!cir::MissingFeatures::armComputeVolatileBitfields()); - const CIRGenBitFieldInfo &info = dst.getBitFieldInfo(); mlir::Type resLTy = convertTypeForMem(dst.getType()); Address ptr = dst.getBitFieldAddress(); - assert(!cir::MissingFeatures::armComputeVolatileBitfields()); + bool useVoaltile = cgm.getCodeGenOpts().AAPCSBitfieldWidth && + dst.isVolatileQualified() && + info.volatileStorageSize != 0 && isAAPCS(cgm.getTarget()); mlir::Value dstAddr = dst.getAddress().getPointer(); return builder.createSetBitfield(dstAddr.getLoc(), resLTy, ptr, ptr.getElementType(), src.getValue(), info, - dst.isVolatileQualified()); + dst.isVolatileQualified(), useVoaltile); } RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) { @@ -348,10 +353,12 @@ RValue CIRGenFunction::emitLoadOfBitfieldLValue(LValue lv, SourceLocation loc) { mlir::Type resLTy = convertType(lv.getType()); Address ptr = lv.getBitFieldAddress(); - assert(!cir::MissingFeatures::armComputeVolatileBitfields()); + bool useVoaltile = lv.isVolatileQualified() && info.volatileOffset != 0 && + isAAPCS(cgm.getTarget()); - mlir::Value field = builder.createGetBitfield( - getLoc(loc), resLTy, ptr, ptr.getElementType(), info, lv.isVolatile()); + mlir::Value field = + builder.createGetBitfield(getLoc(loc), resLTy, ptr, ptr.getElementType(), + info, lv.isVolatile(), useVoaltile); assert(!cir::MissingFeatures::opLoadEmitScalarRangeCheck() && "NYI"); return RValue::get(field); } @@ -376,10 +383,10 @@ LValue CIRGenFunction::emitLValueForBitField(LValue base, const CIRGenRecordLayout &layout = cgm.getTypes().getCIRGenRecordLayout(field->getParent()); const CIRGenBitFieldInfo &info = layout.getBitFieldInfo(field); - assert(!cir::MissingFeatures::armComputeVolatileBitfields()); + assert(!cir::MissingFeatures::preservedAccessIndexRegion()); - unsigned idx = layout.getCIRFieldNo(field); + unsigned idx = layout.getCIRFieldNo(field); Address addr = getAddrOfBitFieldStorage(base, field, info.storageType, idx); mlir::Location loc = getLoc(field->getLocation()); @@ -635,10 +642,8 @@ LValue CIRGenFunction::emitUnaryOpLValue(const UnaryOperator *e) { // Tag 'load' with deref attribute. // FIXME: This misses some derefence cases and has problematic interactions // with other operators. - if (auto loadOp = - dyn_cast<cir::LoadOp>(addr.getPointer().getDefiningOp())) { + if (auto loadOp = addr.getDefiningOp<cir::LoadOp>()) loadOp.setIsDerefAttr(mlir::UnitAttr::get(&getMLIRContext())); - } LValue lv = makeAddrLValue(addr, t, baseInfo); assert(!cir::MissingFeatures::addressSpace()); @@ -1934,6 +1939,20 @@ LValue CIRGenFunction::emitLoadOfReferenceLValue(Address refAddr, pointeeBaseInfo); } +void CIRGenFunction::emitTrap(mlir::Location loc, bool createNewBlock) { + cir::TrapOp::create(builder, loc); + if (createNewBlock) + builder.createBlock(builder.getBlock()->getParent()); +} + +void CIRGenFunction::emitUnreachable(clang::SourceLocation loc, + bool createNewBlock) { + assert(!cir::MissingFeatures::sanitizers()); + cir::UnreachableOp::create(builder, getLoc(loc)); + if (createNewBlock) + builder.createBlock(builder.getBlock()->getParent()); +} + mlir::Value CIRGenFunction::createDummyValue(mlir::Location loc, clang::QualType qt) { mlir::Type t = convertType(qt); @@ -2006,9 +2025,9 @@ cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty, const Twine &name, mlir::Value arraySize, bool insertIntoFnEntryBlock) { - return cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(), - insertIntoFnEntryBlock, arraySize) - .getDefiningOp()); + return mlir::cast<cir::AllocaOp>(emitAlloca(name.str(), ty, loc, CharUnits(), + insertIntoFnEntryBlock, arraySize) + .getDefiningOp()); } /// This creates an alloca and inserts it into the provided insertion point @@ -2018,7 +2037,7 @@ cir::AllocaOp CIRGenFunction::createTempAlloca(mlir::Type ty, mlir::OpBuilder::InsertPoint ip, mlir::Value arraySize) { assert(ip.isSet() && "Insertion point is not set"); - return cast<cir::AllocaOp>( + return mlir::cast<cir::AllocaOp>( emitAlloca(name.str(), ty, loc, CharUnits(), ip, arraySize) .getDefiningOp()); } diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 3ed1e30..eb05c93 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -219,7 +219,9 @@ void CIRGenFunction::declare(mlir::Value addrVal, const Decl *var, QualType ty, assert(isa<NamedDecl>(var) && "Needs a named decl"); assert(!cir::MissingFeatures::cgfSymbolTable()); - auto allocaOp = cast<cir::AllocaOp>(addrVal.getDefiningOp()); + auto allocaOp = addrVal.getDefiningOp<cir::AllocaOp>(); + assert(allocaOp && "expected cir::AllocaOp"); + if (isParam) allocaOp.setInitAttr(mlir::UnitAttr::get(&getMLIRContext())); if (ty->isReferenceType() || ty.isConstQualified()) @@ -381,6 +383,7 @@ void CIRGenFunction::LexicalScope::emitImplicitReturn() { !mayDropFunctionReturn(fd->getASTContext(), fd->getReturnType()); if (shouldEmitUnreachable) { + assert(!cir::MissingFeatures::sanitizers()); if (cgf.cgm.getCodeGenOpts().OptimizationLevel == 0) builder.create<cir::TrapOp>(localScope->endLoc); else diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 68d54bb..3d92545 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1223,8 +1223,28 @@ public: /// to conserve the high level information. mlir::Value emitToMemory(mlir::Value value, clang::QualType ty); + /// Emit a trap instruction, which is used to abort the program in an abnormal + /// way, usually for debugging purposes. + /// \p createNewBlock indicates whether to create a new block for the IR + /// builder. Since the `cir.trap` operation is a terminator, operations that + /// follow a trap cannot be emitted after `cir.trap` in the same block. To + /// ensure these operations get emitted successfully, you need to create a new + /// dummy block and set the insertion point there before continuing from the + /// trap operation. + void emitTrap(mlir::Location loc, bool createNewBlock); + LValue emitUnaryOpLValue(const clang::UnaryOperator *e); + /// Emit a reached-unreachable diagnostic if \p loc is valid and runtime + /// checking is enabled. Otherwise, just emit an unreachable instruction. + /// \p createNewBlock indicates whether to create a new block for the IR + /// builder. Since the `cir.unreachable` operation is a terminator, operations + /// that follow an unreachable point cannot be emitted after `cir.unreachable` + /// in the same block. To ensure these operations get emitted successfully, + /// you need to create a dummy block and set the insertion point there before + /// continuing from the unreachable point. + void emitUnreachable(clang::SourceLocation loc, bool createNewBlock); + /// This method handles emission of any variable declaration /// inside a function, including static vars etc. void emitVarDecl(const clang::VarDecl &d); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index b143682..425250d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1307,7 +1307,8 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { } case Decl::Var: - case Decl::Decomposition: { + case Decl::Decomposition: + case Decl::VarTemplateSpecialization: { auto *vd = cast<VarDecl>(decl); if (isa<DecompositionDecl>(decl)) { errorNYI(decl->getSourceRange(), "global variable decompositions"); @@ -1342,6 +1343,8 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { case Decl::StaticAssert: case Decl::TypeAliasTemplate: case Decl::UsingShadow: + case Decl::VarTemplate: + case Decl::VarTemplatePartialSpecialization: break; case Decl::CXXConstructor: diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp index 32095cb..907cb5f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACC.cpp @@ -119,7 +119,8 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) { if (const auto *memExpr = dyn_cast<MemberExpr>(curVarExpr)) return {exprLoc, emitMemberExpr(memExpr).getPointer(), exprString, - curVarExpr->getType(), std::move(bounds)}; + curVarExpr->getType().getNonReferenceType().getUnqualifiedType(), + std::move(bounds)}; // Sema has made sure that only 4 types of things can get here, array // subscript, array section, member expr, or DRE to a var decl (or the @@ -127,5 +128,6 @@ CIRGenFunction::getOpenACCDataOperandInfo(const Expr *e) { // right. const auto *dre = cast<DeclRefExpr>(curVarExpr); return {exprLoc, emitDeclRefLValue(dre).getPointer(), exprString, - curVarExpr->getType(), std::move(bounds)}; + curVarExpr->getType().getNonReferenceType().getUnqualifiedType(), + std::move(bounds)}; } diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp index 5a6e665..bb9054a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCClause.cpp @@ -358,8 +358,8 @@ class OpenACCClauseCIREmitter final template <typename RecipeTy> RecipeTy getOrCreateRecipe(ASTContext &astCtx, const Expr *varRef, - DeclContext *dc, QualType baseType, - mlir::Value mainOp) { + const VarDecl *varRecipe, DeclContext *dc, + QualType baseType, mlir::Value mainOp) { mlir::ModuleOp mod = builder.getBlock()->getParent()->getParentOfType<mlir::ModuleOp>(); @@ -398,12 +398,6 @@ class OpenACCClauseCIREmitter final auto recipe = RecipeTy::create(modBuilder, loc, recipeName, mainOp.getType()); - // Magic-up a var-decl so we can use normal init/destruction operations for - // a variable declaration. - VarDecl &tempDecl = *VarDecl::Create( - astCtx, dc, varRef->getBeginLoc(), varRef->getBeginLoc(), - &astCtx.Idents.get("openacc.private.init"), baseType, - astCtx.getTrivialTypeSourceInfo(baseType), SC_Auto); CIRGenFunction::AutoVarEmission tempDeclEmission{ CIRGenFunction::AutoVarEmission::invalid()}; @@ -422,9 +416,11 @@ class OpenACCClauseCIREmitter final "OpenACC non-private recipe init"); } - tempDeclEmission = - cgf.emitAutoVarAlloca(tempDecl, builder.saveInsertionPoint()); - cgf.emitAutoVarInit(tempDeclEmission); + if (varRecipe) { + tempDeclEmission = + cgf.emitAutoVarAlloca(*varRecipe, builder.saveInsertionPoint()); + cgf.emitAutoVarInit(tempDeclEmission); + } mlir::acc::YieldOp::create(builder, locEnd); } @@ -439,7 +435,7 @@ class OpenACCClauseCIREmitter final } // Destroy section (doesn't currently exist). - if (tempDecl.needsDestruction(cgf.getContext())) { + if (varRecipe && varRecipe->needsDestruction(cgf.getContext())) { llvm::SmallVector<mlir::Type> argsTys{mainOp.getType()}; llvm::SmallVector<mlir::Location> argsLocs{loc}; mlir::Block *block = builder.createBlock(&recipe.getDestroyRegion(), @@ -450,7 +446,7 @@ class OpenACCClauseCIREmitter final mlir::Type elementTy = mlir::cast<cir::PointerType>(mainOp.getType()).getPointee(); Address addr{block->getArgument(0), elementTy, - cgf.getContext().getDeclAlign(&tempDecl)}; + cgf.getContext().getDeclAlign(varRecipe)}; cgf.emitDestroy(addr, baseType, cgf.getDestroyer(QualType::DK_cxx_destructor)); @@ -1080,9 +1076,10 @@ public: void VisitPrivateClause(const OpenACCPrivateClause &clause) { if constexpr (isOneOfTypes<OpTy, mlir::acc::ParallelOp, mlir::acc::SerialOp, mlir::acc::LoopOp>) { - for (const Expr *var : clause.getVarList()) { + for (const auto [varExpr, varRecipe] : + llvm::zip_equal(clause.getVarList(), clause.getInitRecipes())) { CIRGenFunction::OpenACCDataOperandInfo opInfo = - cgf.getOpenACCDataOperandInfo(var); + cgf.getOpenACCDataOperandInfo(varExpr); auto privateOp = mlir::acc::PrivateOp::create( builder, opInfo.beginLoc, opInfo.varValue, /*structured=*/true, /*implicit=*/false, opInfo.name, opInfo.bounds); @@ -1091,8 +1088,9 @@ public: { mlir::OpBuilder::InsertionGuard guardCase(builder); auto recipe = getOrCreateRecipe<mlir::acc::PrivateRecipeOp>( - cgf.getContext(), var, Decl::castToDeclContext(cgf.curFuncDecl), - opInfo.baseType, privateOp.getResult()); + cgf.getContext(), varExpr, varRecipe, + Decl::castToDeclContext(cgf.curFuncDecl), opInfo.baseType, + privateOp.getResult()); // TODO: OpenACC: The dialect is going to change in the near future to // have these be on a different operation, so when that changes, we // probably need to change these here. diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 8b01d41a..1764967 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -501,11 +501,7 @@ void CIRRecordLowering::accumulateFields() { fieldEnd = recordDecl->field_end(); field != fieldEnd;) { if (field->isBitField()) { - RecordDecl::field_iterator start = field; - // Iterate to gather the list of bitfields. - for (++field; field != fieldEnd && field->isBitField(); ++field) - ; - field = accumulateBitFields(start, field); + field = accumulateBitFields(field, fieldEnd); assert((field == fieldEnd || !field->isBitField()) && "Failed to accumulate all the bitfields"); } else if (!field->isZeroSize(astContext)) { @@ -851,8 +847,9 @@ void CIRRecordLowering::computeVolatileBitfields() { const CharUnits fEnd = fOffset + - astContext.toCharUnitsFromBits(astContext.toBits( - getSizeInBits(cirGenTypes.convertTypeForMem(f->getType())))) - + astContext.toCharUnitsFromBits( + getSizeInBits(cirGenTypes.convertTypeForMem(f->getType())) + .getQuantity()) - CharUnits::One(); // If no overlap, continue. if (end < fOffset || fEnd < storageOffset) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 263ff15..d3fcac1 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -606,7 +606,7 @@ static Value tryFoldCastChain(cir::CastOp op) { if (!isIntOrBoolCast(op)) break; head = op; - op = dyn_cast_or_null<cir::CastOp>(head.getSrc().getDefiningOp()); + op = head.getSrc().getDefiningOp<cir::CastOp>(); } if (head == tail) @@ -1802,7 +1802,7 @@ OpFoldResult cir::UnaryOp::fold(FoldAdaptor adaptor) { } if (isBoolNot(*this)) - if (auto previous = dyn_cast_or_null<UnaryOp>(getInput().getDefiningOp())) + if (auto previous = getInput().getDefiningOp<cir::UnaryOp>()) if (isBoolNot(previous)) return previous.getInput(); @@ -2184,8 +2184,7 @@ LogicalResult cir::ComplexRealOp::verify() { } OpFoldResult cir::ComplexRealOp::fold(FoldAdaptor adaptor) { - if (auto complexCreateOp = - dyn_cast_or_null<cir::ComplexCreateOp>(getOperand().getDefiningOp())) + if (auto complexCreateOp = getOperand().getDefiningOp<cir::ComplexCreateOp>()) return complexCreateOp.getOperand(0); auto complex = @@ -2206,8 +2205,7 @@ LogicalResult cir::ComplexImagOp::verify() { } OpFoldResult cir::ComplexImagOp::fold(FoldAdaptor adaptor) { - if (auto complexCreateOp = - dyn_cast_or_null<cir::ComplexCreateOp>(getOperand().getDefiningOp())) + if (auto complexCreateOp = getOperand().getDefiningOp<cir::ComplexCreateOp>()) return complexCreateOp.getOperand(1); auto complex = diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 895872b..7e1c9fb 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -821,8 +821,7 @@ mlir::LogicalResult CIRToLLVMPtrStrideOpLowering::matchAndRewrite( // before it. To achieve that, look at unary minus, which already got // lowered to "sub 0, x". const auto sub = dyn_cast<mlir::LLVM::SubOp>(indexOp); - auto unary = dyn_cast_if_present<cir::UnaryOp>( - ptrStrideOp.getStride().getDefiningOp()); + auto unary = ptrStrideOp.getStride().getDefiningOp<cir::UnaryOp>(); bool rewriteSub = unary && unary.getKind() == cir::UnaryOpKind::Minus && sub; if (rewriteSub) @@ -2213,7 +2212,8 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMVecShuffleDynamicOpLowering, CIRToLLVMVecShuffleOpLowering, CIRToLLVMVecSplatOpLowering, - CIRToLLVMVecTernaryOpLowering + CIRToLLVMVecTernaryOpLowering, + CIRToLLVMUnreachableOpLowering // clang-format on >(converter, patterns.getContext()); @@ -2269,6 +2269,13 @@ mlir::LogicalResult CIRToLLVMGetMemberOpLowering::matchAndRewrite( } } +mlir::LogicalResult CIRToLLVMUnreachableOpLowering::matchAndRewrite( + cir::UnreachableOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + rewriter.replaceOpWithNewOp<mlir::LLVM::UnreachableOp>(op); + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite( cir::TrapOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -2378,15 +2385,14 @@ mlir::LogicalResult CIRToLLVMVecSplatOpLowering::matchAndRewrite( mlir::Value poison = rewriter.create<mlir::LLVM::PoisonOp>(loc, llvmTy); mlir::Value elementValue = adaptor.getValue(); - if (mlir::isa<mlir::LLVM::PoisonOp>(elementValue.getDefiningOp())) { + if (elementValue.getDefiningOp<mlir::LLVM::PoisonOp>()) { // If the splat value is poison, then we can just use poison value // for the entire vector. rewriter.replaceOp(op, poison); return mlir::success(); } - if (auto constValue = - dyn_cast<mlir::LLVM::ConstantOp>(elementValue.getDefiningOp())) { + if (auto constValue = elementValue.getDefiningOp<mlir::LLVM::ConstantOp>()) { if (auto intAttr = dyn_cast<mlir::IntegerAttr>(constValue.getValue())) { mlir::DenseIntElementsAttr denseVec = mlir::DenseIntElementsAttr::get( mlir::cast<mlir::ShapedType>(llvmTy), intAttr.getValue()); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index f339d43..c5106cb 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -402,6 +402,16 @@ public: mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMUnreachableOpLowering + : public mlir::OpConversionPattern<cir::UnreachableOp> { +public: + using mlir::OpConversionPattern<cir::UnreachableOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::UnreachableOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMTrapOpLowering : public mlir::OpConversionPattern<cir::TrapOp> { public: using mlir::OpConversionPattern<cir::TrapOp>::OpConversionPattern; |