-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mlir][llvm] Replace NullOp by ZeroOp #67183
Conversation
@llvm/pr-subscribers-flang-codegen @llvm/pr-subscribers-mlir-gpu ChangesThis revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only. This is a follow to #65508 Patch is 74.54 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/67183.diff 43 Files Affected:
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 6a6a10f632648cd..9d92086f8d70908 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1150,7 +1150,7 @@ computeElementDistance(mlir::Location loc, mlir::Type ptrTy, mlir::Type idxTy,
// *)0 + 1)' trick for all types. The generated instructions are optimized
// into constant by the first pass of InstCombine, so it should not be a
// performance issue.
- auto nullPtr = rewriter.create<mlir::LLVM::NullOp>(loc, ptrTy);
+ auto nullPtr = rewriter.create<mlir::LLVM::ZeroOp>(loc, ptrTy);
auto gep = rewriter.create<mlir::LLVM::GEPOp>(
loc, ptrTy, nullPtr, llvm::ArrayRef<mlir::LLVM::GEPArg>{1});
return rewriter.create<mlir::LLVM::PtrToIntOp>(loc, idxTy, gep);
@@ -1431,7 +1431,7 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
name, Fortran::semantics::typeInfoBuiltinModule))
fir::emitFatalError(
loc, "runtime derived type info descriptor was not generated");
- return rewriter.create<mlir::LLVM::NullOp>(
+ return rewriter.create<mlir::LLVM::ZeroOp>(
loc, ::getVoidPtrType(mod.getContext()));
}
@@ -1474,7 +1474,7 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
} else {
// Unlimited polymorphic type descriptor with no record type. Set
// type descriptor address to a clean state.
- typeDesc = rewriter.create<mlir::LLVM::NullOp>(
+ typeDesc = rewriter.create<mlir::LLVM::ZeroOp>(
loc, ::getVoidPtrType(mod.getContext()));
}
} else {
@@ -3407,7 +3407,7 @@ struct ZeroOpConversion : public FIROpConversion<fir::ZeroOp> {
mlir::ConversionPatternRewriter &rewriter) const override {
mlir::Type ty = convertType(zero.getType());
if (ty.isa<mlir::LLVM::LLVMPointerType>()) {
- rewriter.replaceOpWithNewOp<mlir::LLVM::NullOp>(zero, ty);
+ rewriter.replaceOpWithNewOp<mlir::LLVM::ZeroOp>(zero, ty);
} else if (ty.isa<mlir::IntegerType>()) {
rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(
zero, ty, mlir::IntegerAttr::get(ty, 0));
@@ -3470,7 +3470,7 @@ struct IsPresentOpConversion : public FIROpConversion<fir::IsPresentOp> {
};
/// Create value signaling an absent optional argument in a call, e.g.
-/// `fir.absent !fir.ref<i64>` --> `llvm.mlir.null : !llvm.ptr<i64>`
+/// `fir.absent !fir.ref<i64>` --> `llvm.mlir.zero : !llvm.ptr<i64>`
struct AbsentOpConversion : public FIROpConversion<fir::AbsentOp> {
using FIROpConversion::FIROpConversion;
@@ -3485,11 +3485,11 @@ struct AbsentOpConversion : public FIROpConversion<fir::AbsentOp> {
assert(!structTy.isOpaque() && !structTy.getBody().empty());
auto undefStruct = rewriter.create<mlir::LLVM::UndefOp>(loc, ty);
auto nullField =
- rewriter.create<mlir::LLVM::NullOp>(loc, structTy.getBody()[0]);
+ rewriter.create<mlir::LLVM::ZeroOp>(loc, structTy.getBody()[0]);
rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
absent, undefStruct, nullField, 0);
} else {
- rewriter.replaceOpWithNewOp<mlir::LLVM::NullOp>(absent, ty);
+ rewriter.replaceOpWithNewOp<mlir::LLVM::ZeroOp>(absent, ty);
}
return mlir::success();
}
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 52716afe3198d91..e39f13ac98268e8 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -145,7 +145,7 @@ func.func @zero_test_ptr() {
return
}
-// CHECK: %{{.*}} = llvm.mlir.null : !llvm.ptr<f32>
+// CHECK: %{{.*}} = llvm.mlir.zero : !llvm.ptr<f32>
// CHECK-NOT: fir.zero_bits
// -----
@@ -201,7 +201,7 @@ func.func @test_alloc_and_freemem_one() {
}
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_one() {
-// CHECK-NEXT: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK-NEXT: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i32>
// CHECK-NEXT: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK-NEXT: %[[N:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK-NEXT: llvm.call @malloc(%[[N]])
@@ -220,7 +220,7 @@ func.func @test_alloc_and_freemem_several() {
}
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_several() {
-// CHECK: [[NULL:%.*]] = llvm.mlir.null : !llvm.ptr<array<100 x f32>>
+// CHECK: [[NULL:%.*]] = llvm.mlir.zero : !llvm.ptr<array<100 x f32>>
// CHECK: [[PTR:%.*]] = llvm.getelementptr [[NULL]][{{.*}}] : (!llvm.ptr<array<100 x f32>>) -> !llvm.ptr<array<100 x f32>>
// CHECK: [[N:%.*]] = llvm.ptrtoint [[PTR]] : !llvm.ptr<array<100 x f32>> to i64
// CHECK: [[MALLOC:%.*]] = llvm.call @malloc([[N]])
@@ -238,7 +238,7 @@ func.func @test_with_shape(%ncols: index, %nrows: index) {
// CHECK-LABEL: llvm.func @test_with_shape
// CHECK-SAME: %[[NCOLS:.*]]: i64, %[[NROWS:.*]]: i64
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f32>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<f32>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[FOUR:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f32> to i64
// CHECK: %[[DIM1_SIZE:.*]] = llvm.mul %[[FOUR]], %[[NCOLS]] : i64
@@ -258,7 +258,7 @@ func.func @test_string_with_shape(%len: index, %nelems: index) {
// CHECK-LABEL: llvm.func @test_string_with_shape
// CHECK-SAME: %[[LEN:.*]]: i64, %[[NELEMS:.*]]: i64)
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i8>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[ONE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i8> to i64
// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[ONE]], %[[LEN]] : i64
@@ -750,7 +750,7 @@ func.func @convert_from_i1(%arg0 : i1) {
// CHECK-LABEL: convert_from_i1(
// CHECK-SAME: %[[ARG0:.*]]: i1
-// CHECK: %{{.*}} = llvm.zext %[[ARG0]] : i1 to i32
+// CHECK: %{{.*}} = llvm.zext %[[ARG0]] : i1 to i32
// -----
@@ -1403,7 +1403,7 @@ func.func @test_absent_i64() -> () {
}
// CHECK-LABEL: @test_absent_i64
-// CHECK-NEXT: %{{.*}} = llvm.mlir.null : !llvm.ptr<i64>
+// CHECK-NEXT: %{{.*}} = llvm.mlir.zero : !llvm.ptr<i64>
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -1412,7 +1412,7 @@ func.func @test_absent_box() -> () {
return
}
// CHECK-LABEL: @test_absent_box
-// CHECK-NEXT: %{{.*}} = llvm.mlir.null : !llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>>
+// CHECK-NEXT: %{{.*}} = llvm.mlir.zero : !llvm.ptr<struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>>
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -1442,7 +1442,7 @@ func.func @absent() -> i1 {
// CHECK-LABEL: @absent
// CHECK-SAME: () -> i1
-// CHECK-NEXT: %[[ptr:.*]] = llvm.mlir.null : !llvm.ptr<i64>
+// CHECK-NEXT: %[[ptr:.*]] = llvm.mlir.zero : !llvm.ptr<i64>
// CHECK-NEXT: %[[ret_val:.*]] = llvm.call @is_present(%[[ptr]]) : (!llvm.ptr<i64>) -> i1
// CHECK-NEXT: llvm.return %[[ret_val]] : i1
@@ -1525,7 +1525,7 @@ func.func @box_tdesc(%arg0: !fir.box<!fir.type<dtdesc{a:i32}>>) {
// CHECK-LABEL: llvm.func @box_tdesc(
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr<struct<(ptr<struct<"dtdesc", (i{{.*}})>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>) {
-// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 7] : (!llvm.ptr<struct<(ptr<struct<"dtdesc", (i{{.*}})>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>) -> !llvm.ptr<ptr<i8>>
+// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ARG0]][0, 7] : (!llvm.ptr<struct<(ptr<struct<"dtdesc", (i{{.*}})>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr<i{{.*}}>, array<1 x i{{.*}}>)>>) -> !llvm.ptr<ptr<i8>>
// CHECK: %[[LOAD:.*]] = llvm.load %[[GEP]] : !llvm.ptr<ptr<i{{.*}}>>
// -----
@@ -1547,7 +1547,7 @@ func.func @embox0(%arg0: !fir.ref<!fir.array<100xi32>>) {
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[C1]] x !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})> {alignment = 8 : i64} : (i32) -> !llvm.ptr<struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>>
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i32>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[I64_ELEM_SIZE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[DESC:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<array<100 x i32>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}})>
@@ -1771,7 +1771,7 @@ func.func @xembox0(%arg0: !fir.ref<!fir.array<?xi32>>) {
// CHECK: %[[ALLOCA:.*]] = llvm.alloca %[[ALLOCA_SIZE]] x !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)> {alignment = 8 : i64} : (i32) -> !llvm.ptr<struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>>
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[TYPE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i32>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
@@ -1820,7 +1820,7 @@ func.func @xembox1(%arg0: !fir.ref<!fir.array<?x!fir.char<1, 10>>>) {
// CHECK-LABEL: llvm.func @xembox1(%{{.*}}: !llvm.ptr<array<10 x i8>>) {
// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : i64) : i64
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<array<10 x i8>>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<array<10 x i8>>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<array<10 x i8>> to i64
// CHECK: %{{.*}} = llvm.insertvalue %[[ELEM_LEN_I64]], %{{.*}}[1] : !llvm.struct<(ptr<array<10 x i8>>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
@@ -1870,7 +1870,7 @@ func.func private @_QPxb(!fir.box<!fir.array<?x?xf64>>)
// CHECK: %[[ARR_SIZE:.*]] = llvm.mul %[[ARR_SIZE_TMP1]], %[[N2]] : i64
// CHECK: %[[ARR:.*]] = llvm.alloca %[[ARR_SIZE]] x f64 {bindc_name = "arr", in_type = !fir.array<?x?xf64>, operandSegmentSizes = array<i32: 0, 2>, uniq_name = "_QFsbEarr"} : (i64) -> !llvm.ptr<f64>
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(28 : i32) : i32
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f64>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<f64>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f64> to i64
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<f64>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i64>>)>
@@ -1949,7 +1949,7 @@ func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)
// CHECK: %[[ALLOCA_SIZE_X:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[X:.*]] = llvm.alloca %[[ALLOCA_SIZE_X]] x !llvm.array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>> {bindc_name = "x", in_type = !fir.array<20x!fir.type<_QFtest_dt_sliceTt{i:i32,j:i32}>>, operandSegmentSizes = array<i32: 0, 0>, uniq_name = "_QFtest_dt_sliceEx"} : (i64) -> !llvm.ptr<array<20 x struct<"_QFtest_dt_sliceTt", (i32, i32)>>>
// CHECK: %[[TYPE_CODE:.*]] = llvm.mlir.constant(9 : i32) : i32
-// CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i32>
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
// CHECK: %[[ELEM_LEN_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i32> to i64
// CHECK: %[[BOX0:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
@@ -1969,7 +1969,7 @@ func.func private @_QPtest_dt_callee(%arg0: !fir.box<!fir.array<?xi32>>)
// CHECK: %[[BOX6:.*]] = llvm.insertvalue %[[F18ADDENDUM_I8]], %[[BOX5]][6] : !llvm.struct<(ptr<i32>, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i64>>)>
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[ONE:.*]] = llvm.mlir.constant(1 : i64) : i64
-// CHECK: %[[ELE_TYPE:.*]] = llvm.mlir.null : !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>
+// CHECK: %[[ELE_TYPE:.*]] = llvm.mlir.zero : !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>
// CHECK: %[[GEP_DTYPE_SIZE:.*]] = llvm.getelementptr %[[ELE_TYPE]][1] : (!llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>) -> !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>>
// CHECK: %[[PTRTOINT_DTYPE_SIZE:.*]] = llvm.ptrtoint %[[GEP_DTYPE_SIZE]] : !llvm.ptr<struct<"_QFtest_dt_sliceTt", (i32, i32)>> to i64
// CHECK: %[[ADJUSTED_OFFSET:.*]] = llvm.sub %[[C1]], %[[ONE]] : i64
@@ -2261,7 +2261,7 @@ func.func @test_rebox_1(%arg0: !fir.box<!fir.array<?x?xf32>>) {
//CHECK: %[[SIX:.*]] = llvm.mlir.constant(6 : index) : i64
//CHECK: %[[EIGHTY:.*]] = llvm.mlir.constant(80 : index) : i64
//CHECK: %[[FLOAT_TYPE:.*]] = llvm.mlir.constant(27 : i32) : i32
-//CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<f32>
+//CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<f32>
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
//CHECK: %[[ELEM_SIZE_I64:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<f32> to i64
//CHECK: %[[RBOX:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<f32>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>)>
@@ -2334,7 +2334,7 @@ func.func @foo(%arg0: !fir.box<!fir.array<?x!fir.type<t{i:i32,c:!fir.char<1,10>}
//CHECK: %[[COMPONENT_OFFSET_1:.*]] = llvm.mlir.constant(1 : i64) : i64
//CHECK: %[[ELEM_COUNT:.*]] = llvm.mlir.constant(7 : i64) : i64
//CHECK: %[[TYPE_CHAR:.*]] = llvm.mlir.constant(40 : i32) : i32
-//CHECK: %[[NULL:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+//CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr<i8>
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
//CHECK: %[[CHAR_SIZE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr<i8> to i64
//CHECK: %[[ELEM_SIZE:.*]] = llvm.mul %[[CHAR_SIZE]], %[[ELEM_COUNT]]
diff --git a/flang/test/Fir/embox-char.fir b/flang/test/Fir/embox-char.fir
index 8a7ef396abab0e4..2e8a826e0b8d501 100644
--- a/flang/test/Fir/embox-char.fir
+++ b/flang/test/Fir/embox-char.fir
@@ -40,7 +40,7 @@
// CHECK: %[[VAL_30_ST0:.*]] = llvm.load %[[VAL_29]] : !llvm.ptr<i64>
// CHECK: %[[VAL_31_LEN:.*]] = llvm.sdiv %[[VAL_16_BYTESIZE]], %[[VAL_13_WIDTH]] : i64
// CHECK: %[[VAL_32:.*]] = llvm.mlir.constant(44 : i32) : i32
-// CHECK: %[[VAL_33:.*]] = llvm.mlir.null : !llvm.ptr<i32>
+// CHECK: %[[VAL_33:.*]] = llvm.mlir.zero : !llvm.ptr<i32>
// CHECK: %[[VAL_34:.*]] = llvm.getelementptr %[[VAL_33]][1] : (!llvm.ptr<i32>) -> !llvm.ptr<i32>
// CHECK: %[[VAL_35:.*]] = llvm.ptrtoint %[[VAL_34]] : !llvm.ptr<i32> to i64
// CHECK: %[[VAL_36_BYTESIZE:.*]] = llvm.mul %[[VAL_35]], %[[VAL_31_LEN]] : i64
@@ -137,7 +137,7 @@ func.func @test_char4(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?x?x!fir.cha
// CHECK: %[[VAL_29:.*]] = llvm.getelementptr %[[VAL_10]][0, 7, %[[VAL_11]], 2] : (!llvm.ptr<struct<(ptr<i8>, i64, i32, i8, i8, i8, i8, array<2 x array<3 x i64>>)>>, i64) -> !llvm.ptr<i64>
// CHECK: %[[VAL_30_ST0:.*]] = llvm.load %[[VAL_29]] : !llvm.ptr<i64>
// CHECK: %[[VAL_32:.*]] = llvm.mlir.constant(40 : i32) : i32
-// CHECK: %[[VAL_33:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+// CHECK: %[[VAL_33:.*]] = llvm.mlir.zero : !llvm.ptr<i8>
// CHECK: %[[VAL_34:.*]] = llvm.getelementptr %[[VAL_33]][1] : (!llvm.ptr<i8>) -> !llvm.ptr<i8>
// CHECK: %[[VAL_35:.*]] = llvm.ptrtoint %[[VAL_34]] : !llvm.ptr<i8> to i64
// CHECK: %[[VAL_36_BYTESIZE:.*]] = llvm.mul %[[VAL_35]], %[[VAL_16_BYTESIZE]] : i64
diff --git a/flang/test/Fir/embox-substring.fir b/flang/test/Fir/embox-substring.fir
index fd0b5923df0ed65..4e2395bc7f34571 100644
--- a/flang/test/Fir/embox-substring.fir
+++ b/flang/test/Fir/embox-substring.fir
@@ -30,7 +30,7 @@ func.func private @dump(!fir.box<!fir.array<2x!fir.char<1>>>)
// CHECK-SAME: %[[VAL_1:.*]]: i64) {
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: llvm.getelementptr
-// CHECK: %[[VAL_28:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+// CHECK: %[[VAL_28:.*]] = llvm.mlir.zero : !llvm.ptr<i8>
// CHECK: %[[VAL_29:.*]] = llvm.getelementptr %[[VAL_28]][1] : (!llvm.ptr<i8>) -> !llvm.ptr<i8>
// CHECK: %[[VAL_30:.*]] = llvm.ptrtoint %[[VAL_29]] : !llvm.ptr<i8> to i64
// CHECK: %[[VAL_31:.*]] = llvm.mul %[[VAL_30]], %[[VAL_1]] : i64
diff --git a/flang/test/Fir/tbaa.fir b/flang/test/Fir/tbaa.fir
index 66bd41bad18e77b..f8a52b2e98db0cc 100644
--- a/flang/test/Fir/tbaa.fir
+++ b/flang/test/Fir/tbaa.fir
@@ -205,7 +205,7 @@ module {
// CHECK-LABEL: llvm.mlir.global internal @_QFEx() {addr_space = 0 : i32} : !llvm.struct<(ptr<struct<()>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)> {
// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(0 : index) : i64
-// CHECK: %[[VAL_1:.*]] = llvm.mlir.null : !llvm.ptr<struct<()>>
+// CHECK: %[[VAL_1:.*]] = llvm.mlir.zero : !llvm.ptr<struct<()>>
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(-1 : i32) : i32
// CHECK: %[[VAL_4:.*]] = llvm.mlir.undef : !llvm.struct<(ptr<struct<()>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>
@@ -223,7 +223,7 @@ module {
// CHECK: %[[VAL_16:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[VAL_17:.*]] = llvm.trunc %[[VAL_16]] : i32 to i8
// CHECK: %[[VAL_18:.*]] = llvm.insertvalue %[[VAL_17]], %[[VAL_15]][6] : !llvm.struct<(ptr<struct<()>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>
-// CHECK: %[[VAL_19:.*]] = llvm.mlir.null : !llvm.ptr<i8>
+// CHECK: %[[VAL_19:.*]] = llvm.mlir.zero : !llvm.ptr<i8>
// CHECK: %[[VAL_20:.*]] = llvm.bitcast %[[VAL_19]] : !llvm.ptr<i8> to !llvm.ptr<i8>
// CHECK: %[[VAL_21:.*]] = llvm.insertvalue %[[VAL_20]], %[[VAL_18]][8] : !llvm.struct<(ptr<struct<()>>, i64, i32, i8, i8, i8, i8, array<1 x array<3 x i64>>, ptr<i8>, array<1 x i64>)>
// CHECK: %[[VAL_22:.*]] = llvm.mlir.constant(0 : i64) : i64
diff --git a/mlir/docs/Dialects/LLVM.md b/mlir/docs/Dialects/LLVM.md
index fa5ce630ad43b01..dae2b03b5d5ceee 100644
--- a/mlir/docs/Dialects/LLVM.md
+++ b/mlir/docs/Dialects/LLVM.md
@@ -106,7 +106,7 @@ are produced by dedicated operations that have the corresponding semantics:
[`llvm.mlir.constant`](#llvmmlirconstant-mlirllvmconstantop),
[`llvm.mlir.undef`](#llvmmlirundef-mlirllvmundefop),
[`llvm.mlir.poison`](#llvmmlirpoison-mlirllvmpoisonop),
-[`llvm.mlir.null`](#llvmmlirnull-mlirllvmnullop). Note how these operations are
+[`llvm.mlir.zero`](#llvmmlirzero-mlirllvmzeroop). Note how these operations are
prefixed with `mlir.` to indicate that they don't belong to LLVM IR but are only
necessary to model it in MLIR. The values produced by these operations are
usable just like any other value.
@@ -118,11 +118,12 @@ Examples:
// by a float.
%0 = llvm.mlir.undef : !llvm.struct<(i32, f32)>
-// Null pointer to i8.
-%1 = llvm.mlir.null : !llvm.ptr<i8>
+// Null pointer.
+%1 = llvm.mlir.zero : !llvm.ptr
-// Null pointer to a function with signatur...
[truncated]
|
This revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only. This is a follow to llvm#65508
48d6a5a
to
81aca3f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There were three breaking changes in LLVM: 1: In the LLVM dialect, NullOp was replaced with a more general ZeroOp. See: llvm/llvm-project#67183. 2: AffineForOp's getInitOperands was renamed to getInits. See: llvm/llvm-project#66925. 3: In the SCF dialect, the WhileOp now implements LoopLikeOpInterface, which now supports multiple loop regions. The getLoopBody member-function was removed in favour of LoopLike's getLoopRegions. The While Op only has a single region, so we can replace calls to getLoopBody with getRegion. See: llvm/llvm-project#66754
There were three breaking changes in LLVM: 1: In the LLVM dialect, NullOp was replaced with a more general ZeroOp. See: llvm/llvm-project#67183. 2: AffineForOp's getInitOperands was renamed to getInits. See: llvm/llvm-project#66925. 3: In the SCF dialect, the WhileOp now implements LoopLikeOpInterface, which now supports multiple loop regions. The getLoopBody member-function was removed in favour of LoopLike's getLoopRegions. The While Op only has a single region, so we can replace calls to getLoopBody with getRegion. See: llvm/llvm-project#66754
There were three breaking changes in LLVM: 1: In the LLVM dialect, NullOp was replaced with a more general ZeroOp. See: llvm/llvm-project#67183. 2: AffineForOp's getInitOperands was renamed to getInits. See: llvm/llvm-project#66925. 3: In the SCF dialect, the WhileOp now implements LoopLikeOpInterface, which now supports multiple loop regions. The getLoopBody member-function was removed in favour of LoopLike's getLoopRegions. The While Op only has a single region, so we can replace calls to getLoopBody with getRegion. See: llvm/llvm-project#66754
There were three breaking changes in LLVM: 1: In the LLVM dialect, NullOp was replaced with a more general ZeroOp. See: llvm/llvm-project#67183. 2: AffineForOp's getInitOperands was renamed to getInits. See: llvm/llvm-project#66925. 3: In the SCF dialect, the WhileOp now implements LoopLikeOpInterface, which now supports multiple loop regions. The getLoopBody member-function was removed in favour of LoopLike's getLoopRegions. The While Op only has a single region, so we can replace calls to getLoopBody with getRegion. See: llvm/llvm-project#66754
**Description of the Change:** NullOp -> ZeroOp llvm/llvm-project#67183 CodeGenOpt -> CodeGenOptLevel https://github.com/llvm/llvm-project/pull/66295/files Converters are const llvm/llvm-project@ce25459 Remove typed pointer llvm/llvm-project#71285 thlo gml_st on ice tensorflow/mlir-hlo@7077cec ByteCode is a new interface llvm/llvm-project@837d1ce getArgsOperandMutable was added CallOpInterface llvm/llvm-project@d790a21 Remove redundant memref.tensor_store op https://github.com/llvm/llvm-project/pull/71010/files Lowering of memref.realloc was extracted to its own pass https://reviews.llvm.org/D159430 **Benefits:** **Possible Drawbacks:** **Related GitHub Issues:** --------- Co-authored-by: erick-xanadu <110487834+erick-xanadu@users.noreply.github.com> Co-authored-by: David Ittah <dime10@users.noreply.github.com>
**Description of the Change:** NullOp -> ZeroOp llvm/llvm-project#67183 CodeGenOpt -> CodeGenOptLevel https://github.com/llvm/llvm-project/pull/66295/files Converters are const llvm/llvm-project@ce25459 Remove typed pointer llvm/llvm-project#71285 thlo gml_st on ice tensorflow/mlir-hlo@7077cec ByteCode is a new interface llvm/llvm-project@837d1ce getArgsOperandMutable was added CallOpInterface llvm/llvm-project@d790a21 Remove redundant memref.tensor_store op https://github.com/llvm/llvm-project/pull/71010/files Lowering of memref.realloc was extracted to its own pass https://reviews.llvm.org/D159430 **Benefits:** **Possible Drawbacks:** **Related GitHub Issues:** --------- Co-authored-by: erick-xanadu <110487834+erick-xanadu@users.noreply.github.com> Co-authored-by: David Ittah <dime10@users.noreply.github.com>
This revision replaces the LLVM dialect NullOp by the recently introduced ZeroOp. The ZeroOp is more generic in the sense that it represents zero values of any LLVM type rather than null pointers only.
This is a follow to #65508