Skip to content

Commit 67f9cd4

Browse files
authored
[mlir][llvm] Fix verifier for const float (#74247)
Fixes one of the cases of #56962. This PR basically moves some code from `mlir::LLVM::detail::getLLVMConstant` ([source](https://github.com/llvm/llvm-project/blob/9f78edbd20ed922cced9482f7791deb9899a6d82/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp#L354-L371)) over to the verifier of `LLVM::ConstantOp`. For now, I focused just on the case where the attribute is a float and ignored the integer case of #56962. Note that without this patch, both added tests will crash inside `getLLVMConstant` during `mlir-translate -mlir-to-llvmir`.
1 parent 3406a2b commit 67f9cd4

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,20 @@ LogicalResult LLVM::ConstantOp::verify() {
25392539
if (!llvm::isa<IntegerAttr, ArrayAttr, FloatAttr, ElementsAttr>(getValue()))
25402540
return emitOpError()
25412541
<< "only supports integer, float, string or elements attributes";
2542+
if (auto floatAttr = dyn_cast<FloatAttr>(getValue())) {
2543+
const llvm::fltSemantics &sem = floatAttr.getValue().getSemantics();
2544+
unsigned floatWidth = APFloat::getSizeInBits(sem);
2545+
if (auto floatTy = dyn_cast<FloatType>(getType())) {
2546+
if (floatTy.getWidth() != floatWidth) {
2547+
return emitOpError() << "expected float type of width " << floatWidth;
2548+
}
2549+
}
2550+
// See the comment for getLLVMConstant for more details about why 8-bit
2551+
// floats can be represented by integers.
2552+
if (getType().isa<IntegerType>() && !getType().isInteger(floatWidth)) {
2553+
return emitOpError() << "expected integer type of width " << floatWidth;
2554+
}
2555+
}
25422556
return success();
25432557
}
25442558

mlir/test/Target/LLVMIR/llvmir-invalid.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ llvm.func @struct_wrong_attribute_element_type() -> !llvm.struct<(f64, f64)> {
3131

3232
// -----
3333

34+
llvm.func @incompatible_float_attribute_type() -> f32 {
35+
// expected-error @below{{expected float type of width 64}}
36+
%cst = llvm.mlir.constant(1.0 : f64) : f32
37+
llvm.return %cst : f32
38+
}
39+
40+
// -----
41+
42+
llvm.func @incompatible_integer_type_for_float_attr() -> i32 {
43+
// expected-error @below{{expected integer type of width 16}}
44+
%cst = llvm.mlir.constant(1.0 : f16) : i32
45+
llvm.return %cst : i32
46+
}
47+
48+
// -----
49+
3450
// expected-error @below{{unsupported constant value}}
3551
llvm.mlir.global internal constant @test([2.5, 7.4]) : !llvm.array<2 x f64>
3652

mlir/test/Target/LLVMIR/llvmir.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ llvm.mlir.global external @explicit_undef() : i32 {
6666
// CHECK: @int_gep = internal constant ptr getelementptr (i32, ptr @i32_global, i32 2)
6767
llvm.mlir.global internal constant @int_gep() : !llvm.ptr {
6868
%addr = llvm.mlir.addressof @i32_global : !llvm.ptr
69-
%_c0 = llvm.mlir.constant(2: i32) :i32
69+
%_c0 = llvm.mlir.constant(2: i32) : i32
7070
%gepinit = llvm.getelementptr %addr[%_c0] : (!llvm.ptr, i32) -> !llvm.ptr, i32
7171
llvm.return %gepinit : !llvm.ptr
7272
}

0 commit comments

Comments
 (0)