Skip to content
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

Merged
merged 1 commit into from
Sep 25, 2023
Merged

[mlir][llvm] Replace NullOp by ZeroOp #67183

merged 1 commit into from
Sep 25, 2023

Conversation

gysit
Copy link
Contributor

@gysit gysit commented Sep 22, 2023

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

@llvmbot llvmbot added mlir:llvm mlir:gpu mlir:sparse Sparse compiler in MLIR mlir flang Flang issues not falling into any other category flang:fir-hlfir flang:codegen labels Sep 22, 2023
@llvmbot
Copy link
Member

llvmbot commented Sep 22, 2023

@llvm/pr-subscribers-flang-codegen
@llvm/pr-subscribers-mlir-sparse
@llvm/pr-subscribers-flang-fir-hlfir
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-mlir-llvm

@llvm/pr-subscribers-mlir-gpu

Changes

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


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:

  • (modified) flang/lib/Optimizer/CodeGen/CodeGen.cpp (+7-7)
  • (modified) flang/test/Fir/convert-to-llvm.fir (+18-18)
  • (modified) flang/test/Fir/embox-char.fir (+2-2)
  • (modified) flang/test/Fir/embox-substring.fir (+1-1)
  • (modified) flang/test/Fir/tbaa.fir (+2-2)
  • (modified) mlir/docs/Dialects/LLVM.md (+6-5)
  • (modified) mlir/include/mlir/Conversion/LLVMCommon/Pattern.h (+1-1)
  • (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (-27)
  • (modified) mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp (+2-2)
  • (modified) mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp (+2-2)
  • (modified) mlir/lib/Conversion/LLVMCommon/Pattern.cpp (+2-2)
  • (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp (+4-4)
  • (modified) mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp (+1-1)
  • (modified) mlir/lib/Target/LLVMIR/ModuleImport.cpp (+1-1)
  • (modified) mlir/test/Conversion/AsyncToLLVM/convert-coro-to-llvm.mlir (+1-1)
  • (modified) mlir/test/Conversion/AsyncToLLVM/convert-runtime-to-llvm.mlir (+1-1)
  • (modified) mlir/test/Conversion/GPUCommon/lower-launch-func-to-gpu-runtime-calls.mlir (+1-1)
  • (modified) mlir/test/Conversion/GPUToVulkan/invoke-vulkan.mlir (+1-1)
  • (modified) mlir/test/Conversion/GPUToVulkan/typed-pointers.mlir (+1-1)
  • (modified) mlir/test/Conversion/MemRefToLLVM/convert-dynamic-memref-ops.mlir (+7-7)
  • (modified) mlir/test/Conversion/MemRefToLLVM/convert-static-memref-ops.mlir (+4-4)
  • (modified) mlir/test/Conversion/MemRefToLLVM/memref-to-llvm.mlir (+3-3)
  • (modified) mlir/test/Conversion/MemRefToLLVM/typed-pointers.mlir (+2-2)
  • (modified) mlir/test/Dialect/GPU/ops.mlir (+1-1)
  • (modified) mlir/test/Dialect/LLVMIR/callgraph.mlir (+2-2)
  • (modified) mlir/test/Dialect/LLVMIR/canonicalize.mlir (+1-1)
  • (modified) mlir/test/Dialect/LLVMIR/invalid.mlir (+3-3)
  • (modified) mlir/test/Dialect/LLVMIR/mem2reg.mlir (+5-5)
  • (modified) mlir/test/Dialect/LLVMIR/roundtrip-typed-pointers.mlir (+4-4)
  • (modified) mlir/test/Dialect/LLVMIR/roundtrip.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/conversion.mlir (+1-1)
  • (modified) mlir/test/Dialect/SparseTensor/convert_dense2sparse.mlir (+4-4)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_concat.mlir (+3-3)
  • (modified) mlir/test/Dialect/SparseTensor/sparse_fill_zero.mlir (+1-1)
  • (modified) mlir/test/Target/LLVMIR/Import/constant.ll (+3-3)
  • (modified) mlir/test/Target/LLVMIR/Import/exception.ll (+2-2)
  • (modified) mlir/test/Target/LLVMIR/Import/instructions.ll (+1-1)
  • (modified) mlir/test/Target/LLVMIR/Import/zeroinitializer.ll (+1-1)
  • (modified) mlir/test/Target/LLVMIR/llvmir-intrinsics.mlir (+4-4)
  • (modified) mlir/test/Target/LLVMIR/llvmir.mlir (+2-2)
  • (modified) mlir/test/Target/LLVMIR/omptarget-declare-target-llvm-host.mlir (+17-17)
  • (modified) mlir/test/Transforms/test-convert-call-op.mlir (+1-1)
  • (modified) mlir/test/lib/Conversion/FuncToLLVM/TestConvertCallOp.cpp (+1-1)
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
Copy link
Contributor

@Dinistro Dinistro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Member

@zero9178 zero9178 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gysit gysit merged commit 85175ed into llvm:main Sep 25, 2023
@rwy7 rwy7 mentioned this pull request Sep 27, 2023
rwy7 added a commit to rwy7/circt that referenced this pull request Sep 27, 2023
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
rwy7 added a commit to rwy7/circt that referenced this pull request Sep 27, 2023
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
rwy7 added a commit to llvm/circt that referenced this pull request Sep 27, 2023
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
mikeurbach pushed a commit to llvm/circt that referenced this pull request Oct 2, 2023
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
rmoyard added a commit to PennyLaneAI/catalyst that referenced this pull request Feb 22, 2024
**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>
rauletorresc pushed a commit to PennyLaneAI/catalyst that referenced this pull request Feb 26, 2024
**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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flang:codegen flang:fir-hlfir flang Flang issues not falling into any other category mlir:gpu mlir:llvm mlir:sparse Sparse compiler in MLIR mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants