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