From f1412a5882ddc57016f060da354395b734cbc1f8 Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Thu, 17 Oct 2024 22:30:27 -0700 Subject: [PATCH] Update [ghstack-poisoned] --- .../include/clang/CIR/Dialect/IR/CIRAttrs.td | 15 +++++++++ clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 8 +++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 32 +++++++++++++------ clang/lib/CIR/Lowering/LoweringHelpers.cpp | 2 +- clang/test/CIR/Lowering/const.cir | 2 ++ clang/test/CIR/Lowering/globals.cir | 7 ++++ 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 292d24315518..19abc9e7bb5f 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -106,6 +106,21 @@ def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> { let assemblyFormat = [{}]; } +//===----------------------------------------------------------------------===// +// UndefAttr +//===----------------------------------------------------------------------===// + +def UndefAttr : CIR_Attr<"Undef", "undef", [TypedAttrInterface]> { + let summary = "Represent an undef constant"; + let description = [{ + The UndefAttr represents an undef constant, corresponding to LLVM's notion + of undef. + }]; + + let parameters = (ins AttributeSelfTypeParameter<"">:$type); + let assemblyFormat = [{}]; +} + //===----------------------------------------------------------------------===// // ConstArrayAttr //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index d01bb735d99c..4508cd586bcb 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -388,6 +388,14 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType, return op->emitOpError("zero expects struct or array type"); } + if (isa(attrType)) { + // Per the LLVM LangRef, "Undefined values may be of any type (other than + // 'label' or 'void')". We don't have label types so we just check for void. + if (!::mlir::isa<::mlir::cir::VoidType>(opType)) + return success(); + return op->emitOpError("undef expects non-void type"); + } + if (mlir::isa(attrType)) { if (!mlir::isa(opType)) return op->emitOpError("result type (") diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index cab778531ada..14f11e33b85c 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -418,6 +418,16 @@ lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::cir::ZeroAttr zeroAttr, loc, converter->convertType(zeroAttr.getType())); } +/// UndefAttr visitor. +inline mlir::Value +lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::cir::UndefAttr undefAttr, + mlir::ConversionPatternRewriter &rewriter, + const mlir::TypeConverter *converter) { + auto loc = parentOp->getLoc(); + return rewriter.create( + loc, converter->convertType(undefAttr.getType())); +} + /// ConstStruct visitor. mlir::Value lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::cir::ConstStructAttr constStruct, @@ -626,6 +636,8 @@ lowerCirAttrAsValue(mlir::Operation *parentOp, mlir::Attribute attr, return lowerCirAttrAsValue(parentOp, boolAttr, rewriter, converter); if (const auto zeroAttr = mlir::dyn_cast(attr)) return lowerCirAttrAsValue(parentOp, zeroAttr, rewriter, converter); + if (const auto undefAttr = mlir::dyn_cast(attr)) + return lowerCirAttrAsValue(parentOp, undefAttr, rewriter, converter); if (const auto globalAttr = mlir::dyn_cast(attr)) return lowerCirAttrAsValue(parentOp, globalAttr, rewriter, converter); if (const auto vtableAttr = mlir::dyn_cast(attr)) @@ -1594,7 +1606,8 @@ class CIRConstantLowering // Fetch operation constant array initializer. auto constArr = mlir::dyn_cast(op.getValue()); - if (!constArr && !isa(op.getValue())) + if (!constArr && + !isa(op.getValue())) return op.emitError() << "array does not have a constant initializer"; std::optional denseAttr; @@ -1626,8 +1639,9 @@ class CIRConstantLowering return mlir::success(); } else if (auto strTy = mlir::dyn_cast(op.getType())) { - if (auto zero = mlir::dyn_cast(op.getValue())) { - auto initVal = lowerCirAttrAsValue(op, zero, rewriter, typeConverter); + auto attr = op.getValue(); + if (mlir::isa(attr)) { + auto initVal = lowerCirAttrAsValue(op, attr, rewriter, typeConverter); rewriter.replaceAllUsesWith(op, initVal); rewriter.eraseOp(op); return mlir::success(); @@ -2315,11 +2329,11 @@ class CIRGlobalOpLowering } else if (auto boolAttr = mlir::dyn_cast(init.value())) { init = rewriter.getBoolAttr(boolAttr.getValue()); - } else if (isa( - init.value())) { - // TODO(cir): once LLVM's dialect has a proper zeroinitializer attribute - // this should be updated. For now, we use a custom op to initialize - // globals to zero. + } else if (isa(init.value())) { + // TODO(cir): once LLVM's dialect has proper equivalent attributes this + // should be updated. For now, we use a custom op to initialize globals + // to the appropriate value. setupRegionInitializedLLVMGlobalOp(op, rewriter); auto value = lowerCirAttrAsValue(op, init.value(), rewriter, typeConverter); @@ -2357,7 +2371,7 @@ class CIRGlobalOpLowering lowerCirAttrAsValue(op, typeinfoAttr, rewriter, typeConverter)); return mlir::success(); } else { - op.emitError() << "usupported initializer '" << init.value() << "'"; + op.emitError() << "unsupported initializer '" << init.value() << "'"; return mlir::failure(); } diff --git a/clang/lib/CIR/Lowering/LoweringHelpers.cpp b/clang/lib/CIR/Lowering/LoweringHelpers.cpp index 94f4d251d370..98d5158ea716 100644 --- a/clang/lib/CIR/Lowering/LoweringHelpers.cpp +++ b/clang/lib/CIR/Lowering/LoweringHelpers.cpp @@ -85,7 +85,7 @@ void convertToDenseElementsAttrImpl( continue; } - if (mlir::isa(eltAttr)) { + if (mlir::isa(eltAttr)) { currentIndex += elementsSizeInCurrentDim; continue; } diff --git a/clang/test/CIR/Lowering/const.cir b/clang/test/CIR/Lowering/const.cir index 4bb234c56995..43e635226000 100644 --- a/clang/test/CIR/Lowering/const.cir +++ b/clang/test/CIR/Lowering/const.cir @@ -15,6 +15,8 @@ module { // CHECK: llvm.mlir.constant(dense<[1.000000e+00, 2.000000e+00]> : tensor<2xf32>) : !llvm.array<2 x f32> %4 = cir.const #cir.zero : !cir.array // CHECK: llvm.mlir.zero : !llvm.array<3 x i32> + %5 = cir.const #cir.undef : !cir.array + // CHECK: llvm.mlir.undef : !llvm.array<3 x i32> cir.return } diff --git a/clang/test/CIR/Lowering/globals.cir b/clang/test/CIR/Lowering/globals.cir index 482ee8490fca..6290ca19c1e0 100644 --- a/clang/test/CIR/Lowering/globals.cir +++ b/clang/test/CIR/Lowering/globals.cir @@ -150,6 +150,13 @@ module { cir.global common @comm = #cir.int<0> : !s32i // MLIR: llvm.mlir.global common @comm(0 : i32) {addr_space = 0 : i32} : i32 + cir.global external @undefStruct = #cir.undef : !ty_Bar + // MLIR: llvm.mlir.global external @undefStruct() + // MLIR: %0 = llvm.mlir.undef : !llvm.struct<"struct.Bar", (i32, i8)> + // MLIR: llvm.return %0 : !llvm.struct<"struct.Bar", (i32, i8)> + // MLIR: } + // LLVM: @undefStruct = global %struct.Bar undef + cir.global "private" internal @Handlers = #cir.const_array<[#cir.const_struct<{#cir.global_view<@myfun> : !cir.ptr>}> : !ty_anon2E1_]> : !cir.array cir.func internal private @myfun(%arg0: !s32i) { %0 = cir.alloca !s32i, !cir.ptr, ["a", init] {alignment = 4 : i64}