@@ -2136,6 +2136,45 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
21362136 rewriter.replaceOp (op, lowerCirAttrAsValue (op, op.getValue (), rewriter,
21372137 getTypeConverter (), dataLayout));
21382138 return mlir::success ();
2139+ } else if (mlir::isa<cir::OpaqueType>(op.getType ())) {
2140+ mlir::Attribute valAttr = op.getValue ();
2141+ mlir::Type llvmTy = getTypeConverter ()->convertType (op.getType ());
2142+ // If the attribute is ZeroAttr or UndefAttr, handle it:
2143+ if (mlir::isa<cir::ZeroAttr, cir::UndefAttr>(valAttr)) {
2144+ // Handle target-ext type
2145+ if (auto tgtExtTy =
2146+ llvm::dyn_cast_or_null<mlir::LLVM::LLVMTargetExtType>(llvmTy)) {
2147+ // Produce a real zero constant if the target-ext type allows it
2148+ if (tgtExtTy.hasProperty (mlir::LLVM::LLVMTargetExtType::HasZeroInit)) {
2149+ if (mlir::isa<cir::ZeroAttr>(valAttr)) {
2150+ auto zero =
2151+ mlir::LLVM::ZeroOp::create (rewriter, op.getLoc (), llvmTy);
2152+ rewriter.replaceOp (op, zero.getResult ());
2153+ return mlir::success ();
2154+ }
2155+ // Fallback: emit an undef of that exact llvm type so users have
2156+ // matching types.
2157+ auto undef =
2158+ mlir::LLVM::UndefOp::create (rewriter, op.getLoc (), llvmTy);
2159+ rewriter.replaceOp (op, undef.getResult ());
2160+ return mlir::success ();
2161+ }
2162+ } else {
2163+ // Target ext type does not support zero init — use `ptr null` of
2164+ // the target-ext type (so users still have the expected type).
2165+ auto ptrTy = mlir::LLVM::LLVMPointerType::get (getContext ());
2166+ auto nullPtr = mlir::LLVM::ZeroOp::create (rewriter, op.getLoc (), ptrTy);
2167+
2168+ rewriter.replaceOp (op, nullPtr.getResult ());
2169+ return mlir::success ();
2170+ }
2171+ }
2172+
2173+ // If the attr is a non-zero concrete value, we must decide if the target
2174+ // expects an encoded representation. Most target-ext types for OpenCL
2175+ // do not accept arbitrary non-zero constants; reject them.
2176+ return op.emitError () << " non-zero constant for target extension type "
2177+ << llvmTy << " is unsupported" ;
21392178 } else
21402179 return op.emitError () << " unsupported constant type " << op.getType ();
21412180
@@ -5190,6 +5229,11 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter,
51905229 converter.addConversion ([&](cir::VoidType type) -> mlir::Type {
51915230 return mlir::LLVM::LLVMVoidType::get (type.getContext ());
51925231 });
5232+
5233+ converter.addConversion ([&, lowerModule](cir::OpaqueType type) -> mlir::Type {
5234+ assert (lowerModule && " LowerModule is not available" );
5235+ return lowerModule->getTargetLoweringInfo ().getOpaqueType (type);
5236+ });
51935237}
51945238
51955239void buildCtorDtorList (
0 commit comments