-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[mlir] Ptr dialect #73057
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
base: main
Are you sure you want to change the base?
[mlir] Ptr dialect #73057
Conversation
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces: - The pointer dialect and type. - The `MemorySpaceAttrInterface` interface, an interface to conceptualize memory models, giving proper semantical meaning to the Ptr dialect ops. - The `ptr::LoadOp` operation, an operation to load data from memory, with the semantics defined by `MemorySpaceAttrInterface` and translatable to LLVM IR. - The `SharedDialectTypeInterface` interface, an interface to delegate printing and parsing to a different dialect. - The introduction of `LLVM::AddressSpaceAttr`, an attribute to model LLVM memory semantics. - The replacement of `LLVMPointerType` with `ptr::PtrType`.
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces: - The pointer dialect and type. - The `MemorySpaceAttrInterface` interface, an interface to conceptualize memory models, giving proper semantical meaning to the Ptr dialect ops. - The `ptr::LoadOp` operation, an operation to load data from memory, with the semantics defined by `MemorySpaceAttrInterface` and translatable to LLVM IR. - The `SharedDialectTypeInterface` interface, an interface to delegate printing and parsing to a different dialect. - The introduction of `LLVM::AddressSpaceAttr`, an attribute to model LLVM memory semantics. - The replacement of `LLVMPointerType` with `ptr::PtrType`.
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces: - The pointer dialect and type. - The `MemorySpaceAttrInterface` interface, an interface to conceptualize memory models, giving proper semantical meaning to the Ptr dialect ops. - The `ptr::LoadOp` operation, an operation to load data from memory, with the semantics defined by `MemorySpaceAttrInterface` and translatable to LLVM IR. - The `SharedDialectTypeInterface` interface, an interface to delegate printing and parsing to a different dialect. - The introduction of `LLVM::AddressSpaceAttr`, an attribute to model LLVM memory semantics. - The replacement of `LLVMPointerType` with `ptr::PtrType`.
@llvm/pr-subscribers-mlir-llvm @llvm/pr-subscribers-backend-amdgpu Author: Fabian Mora (fabianmcg) ChangesThis patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces:
Patch is 773.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73057.diff 187 Files Affected:
diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index 879bc28d017a35..623dd8e88e9a36 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -21,6 +21,7 @@ add_flang_library(FIRCodeGen
FIRDialect
FIRDialectSupport
FIRSupport
+ MLIRPtrDialect
MLIRComplexToLLVM
MLIRComplexToStandard
MLIRMathToFuncs
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 06ce84f1543a3f..fbfe812811c560 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -44,6 +44,7 @@
#include "mlir/Dialect/LLVMIR/Transforms/AddComdats.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/Ptr/IR/PtrDialect.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Pass/Pass.h"
@@ -3615,6 +3616,7 @@ class FIRToLLVMLowering
fir::populateOpenMPFIRToLLVMConversionPatterns(typeConverter, pattern);
mlir::ConversionTarget target{*context};
+ target.addLegalDialect<mlir::ptr::PtrDialect>();
target.addLegalDialect<mlir::LLVM::LLVMDialect>();
// The OpenMP dialect is legal for Operations without regions, for those
// which contains regions it is legal if the region contains only the
diff --git a/flang/lib/Optimizer/Support/CMakeLists.txt b/flang/lib/Optimizer/Support/CMakeLists.txt
index 55f5718a90b854..b98f0988a3d20c 100644
--- a/flang/lib/Optimizer/Support/CMakeLists.txt
+++ b/flang/lib/Optimizer/Support/CMakeLists.txt
@@ -20,6 +20,7 @@ add_flang_library(FIRSupport
MLIROpenACCToLLVMIRTranslation
MLIROpenMPToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
+ MLIRPtrToLLVMIRTranslation
MLIRTargetLLVMIRExport
MLIRTargetLLVMIRImport
diff --git a/flang/lib/Optimizer/Support/InitFIR.cpp b/flang/lib/Optimizer/Support/InitFIR.cpp
index 0753c4511d9c64..c9ef8b35bf0307 100644
--- a/flang/lib/Optimizer/Support/InitFIR.cpp
+++ b/flang/lib/Optimizer/Support/InitFIR.cpp
@@ -11,6 +11,7 @@
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h"
void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
mlir::DialectRegistry registry;
@@ -22,5 +23,7 @@ void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
registerLLVMDialectTranslation(registry);
// Register builtin dialect interface.
registerBuiltinDialectTranslation(registry);
+ // Register ptr dialect interface.
+ registerPtrDialectTranslation(registry);
context.appendDialectRegistry(registry);
}
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index 92628af37085a5..62292bd2b63c3e 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -29,15 +29,15 @@ func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!
// CHECK: omp.parallel {
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
// CHECK: omp.wsloop nowait
// CHECK-SAME: for (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) {
-// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
-// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
+// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: }
// CHECK: omp.terminator
@@ -63,8 +63,8 @@ func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i
// CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}) {
// CHECK: omp.parallel {
// CHECK: omp.master {
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
-// CHECK: llvm.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: omp.terminator
@@ -99,7 +99,7 @@ func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[C50:.*]] = llvm.mlir.constant(50 : i32) : i32
// CHECK: omp.wsloop for (%[[INDX:.*]]) : i32 = (%[[C1]]) to (%[[C50]]) inclusive step (%[[C1]]) {
-// CHECK: llvm.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
+// CHECK: ptr.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: omp.terminator
// CHECK: llvm.return
@@ -201,15 +201,15 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK: omp.parallel {
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
// CHECK: omp.simdloop
// CHECK-SAME: (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
-// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
-// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
+// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: }
// CHECK: omp.terminator
@@ -386,24 +386,24 @@ func.func @_QPopenmp_target_data_region() {
// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64
// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3
// CHECK: ^bb2:
-// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
-// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
-// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
+// CHECK: %[[VAL_17:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: %[[VAL_18:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64
// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64
// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32
-// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: %[[VAL_25:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32
// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64
// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64)
// CHECK: ^bb3:
-// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
@@ -463,7 +463,7 @@ func.func @_QPomp_target() {
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_7:.*]] = llvm.getelementptr %[[ARG_0]][0, %[[VAL_6]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
@@ -669,9 +669,9 @@ func.func @_QPsb() {
// CHECK: %[[EXIT_COND:.*]] = llvm.icmp "sgt"
// CHECK: llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]]
// CHECK: ^[[BB_LOOP_BODY]]:
-// CHECK: %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr -> i32
+// CHECK: %[[LI_VAL:.*]] = ptr.load %[[LI_REF]] : !llvm.ptr -> i32
// CHECK: %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]] : i32
-// CHECK: llvm.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
// CHECK: llvm.br ^[[BB_ENTRY]]({{.*}})
// CHECK: ^[[BB_EXIT]]:
// CHECK: omp.terminator
@@ -703,15 +703,15 @@ func.func @_QPsb() {
// CHECK: omp.parallel {
// CHECK: omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) for
// CHECK: %[[ARRAY_ELEM_REF:.*]] = llvm.getelementptr %[[ARRAY_REF]][0, %{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: %[[ARRAY_ELEM:.*]] = llvm.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
-// CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> i32
+// CHECK: %[[ARRAY_ELEM:.*]] = ptr.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
+// CHECK: %[[LPRV:.+]] = ptr.load %[[PRV]] : !llvm.ptr -> i32
// CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32
// CHECK: %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[LPRV]], %[[ZERO_1]] : i32
// CHECK: %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32
// CHECK: %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARRAY_ELEM]], %[[ZERO_2]] : i32
// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_2]], %[[ARGVAL_1]] : i1
// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
-// CHECK: llvm.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: omp.terminator
// CHECK: llvm.return
@@ -781,10 +781,10 @@ func.func @_QPs(%arg0: !fir.ref<!fir.complex<4>> {fir.bindc_name = "x"}) {
//CHECK: omp.parallel {
//CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
//CHECK: %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
-//CHECK: %[[LOAD:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
-//CHECK: llvm.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
+//CHECK: %[[LOAD:.*]] = ptr.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
+//CHECK: ptr.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr) -> !llvm.ptr
-//CHECK: %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
+//CHECK: %[[LOAD_2:.*]] = ptr.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
//CHECK: omp.terminator
//CHECK: }
@@ -864,13 +864,13 @@ func.func @sub_() {
omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
// CHECK: omp.flush
omp.flush
-// CHECK: %[[A_VAL:.*]] = llvm.load %[[ARG_A]] : !llvm.ptr -> i32
+// CHECK: %[[A_VAL:.*]] = ptr.load %[[ARG_A]] : !llvm.ptr -> i32
%0 = fir.load %arg0 : !fir.ref<i32>
-// CHECK: %[[B_VAL:.*]] = llvm.load %[[ARG_B]] : !llvm.ptr -> i32
+// CHECK: %[[B_VAL:.*]] = ptr.load %[[ARG_B]] : !llvm.ptr -> i32
%1 = fir.load %arg1 : !fir.ref<i32>
// CHECK: %[[C_VAL:.*]] = llvm.add %[[A_VAL]], %[[B_VAL]] : i32
%2 = arith.addi %0, %1 : i32
-// CHECK: llvm.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
fir.store %2 to %arg2 : !fir.ref<i32>
// CHECK: omp.terminator
omp.terminator
@@ -892,13 +892,13 @@ func.func @omp_critical_() {
%1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"}
// CHECK: omp.critical(@help)
omp.critical(@help) {
-// CHECK: %[[X_VAL:.*]] = llvm.load %[[X_REF]] : !llvm.ptr -> i32
+// CHECK: %[[X_VAL:.*]] = ptr.load %[[X_REF]] : !llvm.ptr -> i32
%2 = fir.load %0 : !fir.ref<i32>
-// CHECK: %[[Y_VAL:.*]] = llvm.load %[[Y_REF]] : !llvm.ptr -> i32
+// CHECK: %[[Y_VAL:.*]] = ptr.load %[[Y_REF]] : !llvm.ptr -> i32
%3 = fir.load %1 : !fir.ref<i32>
// CHECK: %[[RESULT:.*]] = llvm.add %[[X_VAL]], %[[Y_VAL]] : i32
%4 = arith.addi %2, %3 : i32
-// CHECK: llvm.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
fir.store %4 to %0 : !fir.ref<i32>
// CHECK: omp.terminator
omp.terminator
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 21323a5e657c94..93fcb7315a437d 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -218,7 +218,7 @@ func.func @test_alloc_and_freemem_one() {
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_one() {
// CHECK-NEXT: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK-NEXT: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK-NEXT: %[[N:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK-NEXT: %[[N:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK-NEXT: llvm.call @malloc(%[[N]])
// CHECK: llvm.call @free(%{{.*}})
// CHECK-NEXT: llvm.return
@@ -237,7 +237,7 @@ func.func @test_alloc_and_freemem_several() {
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_several() {
// CHECK: [[NULL:%.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: [[PTR:%.*]] = llvm.getelementptr [[NULL]][{{.*}}] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<100 x f32>
-// CHECK: [[N:%.*]] = llvm.ptrtoint [[PTR]] : !llvm.ptr to i64
+// CHECK: [[N:%.*]] = ptr.ptrtoint [[PTR]] : !llvm.ptr to i64
// CHECK: [[MALLOC:%.*]] = llvm.call @malloc([[N]])
// CHECK: llvm.call @free([[MALLOC]])
// CHECK: llvm.return
@@ -253,7 +253,7 @@ func.func @test_with_shape(%ncols: index, %nrows: index) {
// CHECK-SAME: %[[NCOLS:.*]]: i64, %[[NROWS:.*]]: i64
// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK: %[[FOUR:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK: %[[FOUR:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK: %[[DIM1_SIZE:.*]] = llvm.mul %[[FOUR]], %[[NCOLS]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[DIM1_SIZE]], %[[NROWS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
@@ -271,7 +271,7 @@ func.func @test_string_with_shape(%len: index, %nelems: index) {
// CHECK-SAME: %[[LEN:.*]]: i64, %[[NELEMS:.*]]: i64)
// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK: %[[ONE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK: %[[ONE:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[ONE]], %[[LEN]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[LEN_SIZE]], %[[NELEMS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
@@ -749,7 +749,7 @@ func.func @convert_from_int(%arg0 : i32) {
// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i16
// CHECK-NOT: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i32
// CHECK: %{{.*}} = llvm.sext %[[ARG0]] : i32 to i64
-// CHECK: %{{.*}} = llvm.inttoptr %{{.*}} : i64 to !llvm.ptr
+// CHECK: %{{.*}} = ptr.inttoptr %{{.*}} : i64 to !llvm.ptr
func.func @convert_from_i1(%arg0 : i1) {
@@ -774,7 +774,7 @@ func.func @convert_from_ref(%arg0 : !fir.ref<i32>) {
// CHECK-LABEL: convert_from_ref(
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr
// CHECK-NOT: %{{.*}} = llvm.bitcast %[[ARG0]] : !llvm.ptr to !llvm.ptr
-// CHECK: %{{.*}} = llvm.ptrtoint %[[ARG0]] : !llvm.ptr to i32
+// CHECK: %{{.*}} = ptr.ptrtoint %[[ARG0]] : !llvm.ptr to i32
// -----
@@ -848,7 +848,7 @@ func.func @test_constc8() -> !fir.complex<8> {
// -----
-// Test `fir.store` --> `llvm.store` conversion
+// Test `fir.store` --> `ptr.store` conversion
func.func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) {
fir.store %val_to_store to %addr : !fir.ref<index>
@@ -857,7 +857,7 @@ func.func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) {
// CHECK-LABEL: llvm.func @test_store_index
// CHECK-SAME: (%[[arg0:.*]]: i64, %[[arg1:.*]]: !llvm.ptr) {
-// CHECK-NEXT: llvm.store %[[arg0]], %[[arg1]] : i64, !llvm.ptr
+// CHECK-NEXT: ptr.store %[[arg0]], %[[arg1]] : i64, !llvm.ptr
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -869,8 +869,8 @@ func.func @test_store_box(%array : !fir.ref<!fir.box<!fir.array<?x?xf32>>>, %box
// CHECK-LABEL: llvm.func @test_store_box
// CHECK-SAME: (%[[arg0:.*]]: !llvm.ptr,
// CHECK-SAME: %[[arg1:.*]]: !llvm.ptr) {
-// CHECK-NEXT: %[[box_to_store:.*]] = llvm.load %arg1 : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>
-// CHECK-NEXT: llvm.store %[[box_to_store]], %[[arg0]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>, !llvm.ptr
+// CHECK-NEXT: %[[box_to_store:.*]] = ptr.load %arg1 : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>
+// CHECK-NEXT: ptr.store %[[box_to_store]], %[[arg0]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>, !llvm.ptr
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -883,19 +883,19 @@ func.func @store_unlimited_polymorphic_box(%arg0 : !fir.class<none>, %arg1 : !fi
return
}
// CHECK-LABEL: llvm.func @store_unlimited_polymorphic_box(
-// CHECK: %[[VAL_8:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_8]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_9:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_9]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_10:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_10]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_11:.*]] = ll...
[truncated]
|
@llvm/pr-subscribers-flang-openmp Author: Fabian Mora (fabianmcg) ChangesThis patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect. More specifically, this patch introduces:
Patch is 773.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73057.diff 187 Files Affected:
diff --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index 879bc28d017a35..623dd8e88e9a36 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -21,6 +21,7 @@ add_flang_library(FIRCodeGen
FIRDialect
FIRDialectSupport
FIRSupport
+ MLIRPtrDialect
MLIRComplexToLLVM
MLIRComplexToStandard
MLIRMathToFuncs
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 06ce84f1543a3f..fbfe812811c560 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -44,6 +44,7 @@
#include "mlir/Dialect/LLVMIR/Transforms/AddComdats.h"
#include "mlir/Dialect/OpenACC/OpenACC.h"
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/Ptr/IR/PtrDialect.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Matchers.h"
#include "mlir/Pass/Pass.h"
@@ -3615,6 +3616,7 @@ class FIRToLLVMLowering
fir::populateOpenMPFIRToLLVMConversionPatterns(typeConverter, pattern);
mlir::ConversionTarget target{*context};
+ target.addLegalDialect<mlir::ptr::PtrDialect>();
target.addLegalDialect<mlir::LLVM::LLVMDialect>();
// The OpenMP dialect is legal for Operations without regions, for those
// which contains regions it is legal if the region contains only the
diff --git a/flang/lib/Optimizer/Support/CMakeLists.txt b/flang/lib/Optimizer/Support/CMakeLists.txt
index 55f5718a90b854..b98f0988a3d20c 100644
--- a/flang/lib/Optimizer/Support/CMakeLists.txt
+++ b/flang/lib/Optimizer/Support/CMakeLists.txt
@@ -20,6 +20,7 @@ add_flang_library(FIRSupport
MLIROpenACCToLLVMIRTranslation
MLIROpenMPToLLVMIRTranslation
MLIRLLVMToLLVMIRTranslation
+ MLIRPtrToLLVMIRTranslation
MLIRTargetLLVMIRExport
MLIRTargetLLVMIRImport
diff --git a/flang/lib/Optimizer/Support/InitFIR.cpp b/flang/lib/Optimizer/Support/InitFIR.cpp
index 0753c4511d9c64..c9ef8b35bf0307 100644
--- a/flang/lib/Optimizer/Support/InitFIR.cpp
+++ b/flang/lib/Optimizer/Support/InitFIR.cpp
@@ -11,6 +11,7 @@
#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenACC/OpenACCToLLVMIRTranslation.h"
#include "mlir/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.h"
+#include "mlir/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.h"
void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
mlir::DialectRegistry registry;
@@ -22,5 +23,7 @@ void fir::support::registerLLVMTranslation(mlir::MLIRContext &context) {
registerLLVMDialectTranslation(registry);
// Register builtin dialect interface.
registerBuiltinDialectTranslation(registry);
+ // Register ptr dialect interface.
+ registerPtrDialectTranslation(registry);
context.appendDialectRegistry(registry);
}
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index 92628af37085a5..62292bd2b63c3e 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -29,15 +29,15 @@ func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!
// CHECK: omp.parallel {
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
// CHECK: omp.wsloop nowait
// CHECK-SAME: for (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) {
-// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
-// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
+// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: }
// CHECK: omp.terminator
@@ -63,8 +63,8 @@ func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i
// CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr {fir.bindc_name = "n"}) {
// CHECK: omp.parallel {
// CHECK: omp.master {
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
-// CHECK: llvm.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[N]], %[[X_REF]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: omp.terminator
@@ -99,7 +99,7 @@ func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[C50:.*]] = llvm.mlir.constant(50 : i32) : i32
// CHECK: omp.wsloop for (%[[INDX:.*]]) : i32 = (%[[C1]]) to (%[[C50]]) inclusive step (%[[C1]]) {
-// CHECK: llvm.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
+// CHECK: ptr.store %[[INDX]], %{{.*}} : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: omp.terminator
// CHECK: llvm.return
@@ -201,15 +201,15 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK: omp.parallel {
// CHECK: %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {pinned} : (i64) -> !llvm.ptr
-// CHECK: %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr -> i32
+// CHECK: %[[N:.*]] = ptr.load %[[N_REF]] : !llvm.ptr -> i32
// CHECK: omp.simdloop
// CHECK-SAME: (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) step (%[[ONE_2]]) {
-// CHECK: llvm.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
-// CHECK: %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[I]], %[[I_VAR]] : i32, !llvm.ptr
+// CHECK: %[[I1:.*]] = ptr.load %[[I_VAR]] : !llvm.ptr -> i32
// CHECK: %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
// CHECK: %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]] : i64
// CHECK: %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[I1]], %[[ARR_I_REF]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: }
// CHECK: omp.terminator
@@ -386,24 +386,24 @@ func.func @_QPopenmp_target_data_region() {
// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64
// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3
// CHECK: ^bb2:
-// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
-// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
-// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
+// CHECK: %[[VAL_17:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: %[[VAL_18:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64
// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64
// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr
// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32
-// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32
+// CHECK: %[[VAL_25:.*]] = ptr.load %[[VAL_3]] : !llvm.ptr -> i32
// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32
// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64
// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64)
// CHECK: ^bb3:
-// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_13]], %[[VAL_3]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
@@ -463,7 +463,7 @@ func.func @_QPomp_target() {
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_7:.*]] = llvm.getelementptr %[[ARG_0]][0, %[[VAL_6]]] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: llvm.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[VAL_3]], %[[VAL_7]] : i32, !llvm.ptr
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
@@ -669,9 +669,9 @@ func.func @_QPsb() {
// CHECK: %[[EXIT_COND:.*]] = llvm.icmp "sgt"
// CHECK: llvm.cond_br %[[EXIT_COND]], ^[[BB_LOOP_BODY:.*]], ^[[BB_EXIT:.*]]
// CHECK: ^[[BB_LOOP_BODY]]:
-// CHECK: %[[LI_VAL:.*]] = llvm.load %[[LI_REF]] : !llvm.ptr -> i32
+// CHECK: %[[LI_VAL:.*]] = ptr.load %[[LI_REF]] : !llvm.ptr -> i32
// CHECK: %[[LI_INC:.*]] = llvm.add %[[LI_VAL]], %[[ONE]] : i32
-// CHECK: llvm.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[LI_INC]], %[[LI_REF]] : i32, !llvm.ptr
// CHECK: llvm.br ^[[BB_ENTRY]]({{.*}})
// CHECK: ^[[BB_EXIT]]:
// CHECK: omp.terminator
@@ -703,15 +703,15 @@ func.func @_QPsb() {
// CHECK: omp.parallel {
// CHECK: omp.wsloop reduction(@[[EQV_REDUCTION]] %[[RED_ACCUMULATOR]] -> %[[PRV:.+]] : !llvm.ptr) for
// CHECK: %[[ARRAY_ELEM_REF:.*]] = llvm.getelementptr %[[ARRAY_REF]][0, %{{.*}}] : (!llvm.ptr, i64) -> !llvm.ptr
-// CHECK: %[[ARRAY_ELEM:.*]] = llvm.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
-// CHECK: %[[LPRV:.+]] = llvm.load %[[PRV]] : !llvm.ptr -> i32
+// CHECK: %[[ARRAY_ELEM:.*]] = ptr.load %[[ARRAY_ELEM_REF]] : !llvm.ptr -> i32
+// CHECK: %[[LPRV:.+]] = ptr.load %[[PRV]] : !llvm.ptr -> i32
// CHECK: %[[ZERO_1:.*]] = llvm.mlir.constant(0 : i64) : i32
// CHECK: %[[ARGVAL_1:.*]] = llvm.icmp "ne" %[[LPRV]], %[[ZERO_1]] : i32
// CHECK: %[[ZERO_2:.*]] = llvm.mlir.constant(0 : i64) : i32
// CHECK: %[[ARGVAL_2:.*]] = llvm.icmp "ne" %[[ARRAY_ELEM]], %[[ZERO_2]] : i32
// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_2]], %[[ARGVAL_1]] : i1
// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
-// CHECK: llvm.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[RES_EXT]], %[[PRV]] : i32, !llvm.ptr
// CHECK: omp.yield
// CHECK: omp.terminator
// CHECK: llvm.return
@@ -781,10 +781,10 @@ func.func @_QPs(%arg0: !fir.ref<!fir.complex<4>> {fir.bindc_name = "x"}) {
//CHECK: omp.parallel {
//CHECK: %[[CONST_1:.*]] = llvm.mlir.constant(1 : i32) : i32
//CHECK: %[[ALLOCA_1:.*]] = llvm.alloca %[[CONST_1:.*]] x !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)> {alignment = 8 : i64} : (i32) -> !llvm.ptr
-//CHECK: %[[LOAD:.*]] = llvm.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
-//CHECK: llvm.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
+//CHECK: %[[LOAD:.*]] = ptr.load %[[ALLOCA]] : !llvm.ptr -> !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>
+//CHECK: ptr.store %[[LOAD]], %[[ALLOCA_1]] : !llvm.struct<(ptr, i64, i32, i8, i8, i8, i8)>, !llvm.ptr
//CHECK: %[[GEP:.*]] = llvm.getelementptr %[[ALLOCA_1]][0, 0] : (!llvm.ptr) -> !llvm.ptr
-//CHECK: %[[LOAD_2:.*]] = llvm.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
+//CHECK: %[[LOAD_2:.*]] = ptr.load %[[GEP]] : !llvm.ptr -> !llvm.ptr
//CHECK: omp.terminator
//CHECK: }
@@ -864,13 +864,13 @@ func.func @sub_() {
omp.flush(%arg0, %arg1, %arg2 : !fir.ref<i32>, !fir.ref<i32>, !fir.ref<i32>)
// CHECK: omp.flush
omp.flush
-// CHECK: %[[A_VAL:.*]] = llvm.load %[[ARG_A]] : !llvm.ptr -> i32
+// CHECK: %[[A_VAL:.*]] = ptr.load %[[ARG_A]] : !llvm.ptr -> i32
%0 = fir.load %arg0 : !fir.ref<i32>
-// CHECK: %[[B_VAL:.*]] = llvm.load %[[ARG_B]] : !llvm.ptr -> i32
+// CHECK: %[[B_VAL:.*]] = ptr.load %[[ARG_B]] : !llvm.ptr -> i32
%1 = fir.load %arg1 : !fir.ref<i32>
// CHECK: %[[C_VAL:.*]] = llvm.add %[[A_VAL]], %[[B_VAL]] : i32
%2 = arith.addi %0, %1 : i32
-// CHECK: llvm.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[C_VAL]], %[[ARG_C]] : i32, !llvm.ptr
fir.store %2 to %arg2 : !fir.ref<i32>
// CHECK: omp.terminator
omp.terminator
@@ -892,13 +892,13 @@ func.func @omp_critical_() {
%1 = fir.alloca i32 {bindc_name = "y", uniq_name = "_QFomp_criticalEy"}
// CHECK: omp.critical(@help)
omp.critical(@help) {
-// CHECK: %[[X_VAL:.*]] = llvm.load %[[X_REF]] : !llvm.ptr -> i32
+// CHECK: %[[X_VAL:.*]] = ptr.load %[[X_REF]] : !llvm.ptr -> i32
%2 = fir.load %0 : !fir.ref<i32>
-// CHECK: %[[Y_VAL:.*]] = llvm.load %[[Y_REF]] : !llvm.ptr -> i32
+// CHECK: %[[Y_VAL:.*]] = ptr.load %[[Y_REF]] : !llvm.ptr -> i32
%3 = fir.load %1 : !fir.ref<i32>
// CHECK: %[[RESULT:.*]] = llvm.add %[[X_VAL]], %[[Y_VAL]] : i32
%4 = arith.addi %2, %3 : i32
-// CHECK: llvm.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
+// CHECK: ptr.store %[[RESULT]], %[[X_REF]] : i32, !llvm.ptr
fir.store %4 to %0 : !fir.ref<i32>
// CHECK: omp.terminator
omp.terminator
diff --git a/flang/test/Fir/convert-to-llvm.fir b/flang/test/Fir/convert-to-llvm.fir
index 21323a5e657c94..93fcb7315a437d 100644
--- a/flang/test/Fir/convert-to-llvm.fir
+++ b/flang/test/Fir/convert-to-llvm.fir
@@ -218,7 +218,7 @@ func.func @test_alloc_and_freemem_one() {
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_one() {
// CHECK-NEXT: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK-NEXT: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK-NEXT: %[[N:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK-NEXT: %[[N:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK-NEXT: llvm.call @malloc(%[[N]])
// CHECK: llvm.call @free(%{{.*}})
// CHECK-NEXT: llvm.return
@@ -237,7 +237,7 @@ func.func @test_alloc_and_freemem_several() {
// CHECK-LABEL: llvm.func @test_alloc_and_freemem_several() {
// CHECK: [[NULL:%.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: [[PTR:%.*]] = llvm.getelementptr [[NULL]][{{.*}}] : (!llvm.ptr) -> !llvm.ptr, !llvm.array<100 x f32>
-// CHECK: [[N:%.*]] = llvm.ptrtoint [[PTR]] : !llvm.ptr to i64
+// CHECK: [[N:%.*]] = ptr.ptrtoint [[PTR]] : !llvm.ptr to i64
// CHECK: [[MALLOC:%.*]] = llvm.call @malloc([[N]])
// CHECK: llvm.call @free([[MALLOC]])
// CHECK: llvm.return
@@ -253,7 +253,7 @@ func.func @test_with_shape(%ncols: index, %nrows: index) {
// CHECK-SAME: %[[NCOLS:.*]]: i64, %[[NROWS:.*]]: i64
// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK: %[[FOUR:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK: %[[FOUR:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK: %[[DIM1_SIZE:.*]] = llvm.mul %[[FOUR]], %[[NCOLS]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[DIM1_SIZE]], %[[NROWS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
@@ -271,7 +271,7 @@ func.func @test_string_with_shape(%len: index, %nelems: index) {
// CHECK-SAME: %[[LEN:.*]]: i64, %[[NELEMS:.*]]: i64)
// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr
// CHECK: %[[GEP:.*]] = llvm.getelementptr %[[NULL]][1]
-// CHECK: %[[ONE:.*]] = llvm.ptrtoint %[[GEP]] : !llvm.ptr to i64
+// CHECK: %[[ONE:.*]] = ptr.ptrtoint %[[GEP]] : !llvm.ptr to i64
// CHECK: %[[LEN_SIZE:.*]] = llvm.mul %[[ONE]], %[[LEN]] : i64
// CHECK: %[[TOTAL_SIZE:.*]] = llvm.mul %[[LEN_SIZE]], %[[NELEMS]] : i64
// CHECK: %[[MEM:.*]] = llvm.call @malloc(%[[TOTAL_SIZE]])
@@ -749,7 +749,7 @@ func.func @convert_from_int(%arg0 : i32) {
// CHECK: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i16
// CHECK-NOT: %{{.*}} = llvm.trunc %[[ARG0]] : i32 to i32
// CHECK: %{{.*}} = llvm.sext %[[ARG0]] : i32 to i64
-// CHECK: %{{.*}} = llvm.inttoptr %{{.*}} : i64 to !llvm.ptr
+// CHECK: %{{.*}} = ptr.inttoptr %{{.*}} : i64 to !llvm.ptr
func.func @convert_from_i1(%arg0 : i1) {
@@ -774,7 +774,7 @@ func.func @convert_from_ref(%arg0 : !fir.ref<i32>) {
// CHECK-LABEL: convert_from_ref(
// CHECK-SAME: %[[ARG0:.*]]: !llvm.ptr
// CHECK-NOT: %{{.*}} = llvm.bitcast %[[ARG0]] : !llvm.ptr to !llvm.ptr
-// CHECK: %{{.*}} = llvm.ptrtoint %[[ARG0]] : !llvm.ptr to i32
+// CHECK: %{{.*}} = ptr.ptrtoint %[[ARG0]] : !llvm.ptr to i32
// -----
@@ -848,7 +848,7 @@ func.func @test_constc8() -> !fir.complex<8> {
// -----
-// Test `fir.store` --> `llvm.store` conversion
+// Test `fir.store` --> `ptr.store` conversion
func.func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) {
fir.store %val_to_store to %addr : !fir.ref<index>
@@ -857,7 +857,7 @@ func.func @test_store_index(%val_to_store : index, %addr : !fir.ref<index>) {
// CHECK-LABEL: llvm.func @test_store_index
// CHECK-SAME: (%[[arg0:.*]]: i64, %[[arg1:.*]]: !llvm.ptr) {
-// CHECK-NEXT: llvm.store %[[arg0]], %[[arg1]] : i64, !llvm.ptr
+// CHECK-NEXT: ptr.store %[[arg0]], %[[arg1]] : i64, !llvm.ptr
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -869,8 +869,8 @@ func.func @test_store_box(%array : !fir.ref<!fir.box<!fir.array<?x?xf32>>>, %box
// CHECK-LABEL: llvm.func @test_store_box
// CHECK-SAME: (%[[arg0:.*]]: !llvm.ptr,
// CHECK-SAME: %[[arg1:.*]]: !llvm.ptr) {
-// CHECK-NEXT: %[[box_to_store:.*]] = llvm.load %arg1 : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>
-// CHECK-NEXT: llvm.store %[[box_to_store]], %[[arg0]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>, !llvm.ptr
+// CHECK-NEXT: %[[box_to_store:.*]] = ptr.load %arg1 : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>
+// CHECK-NEXT: ptr.store %[[box_to_store]], %[[arg0]] : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<2 x array<3 x i{{.*}}>>)>, !llvm.ptr
// CHECK-NEXT: llvm.return
// CHECK-NEXT: }
@@ -883,19 +883,19 @@ func.func @store_unlimited_polymorphic_box(%arg0 : !fir.class<none>, %arg1 : !fi
return
}
// CHECK-LABEL: llvm.func @store_unlimited_polymorphic_box(
-// CHECK: %[[VAL_8:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_8]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_9:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_9]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, array<1 x array<3 x i{{.*}}>>, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_10:.*]] = llvm.load %{{.*}} : !llvm.ptr -> !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>
-// CHECK: llvm.store %[[VAL_10]], %{{.*}} : !llvm.struct<(ptr, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, i{{.*}}, ptr, array<1 x i{{.*}}>)>, !llvm.ptr
-// CHECK: %[[VAL_11:.*]] = ll...
[truncated]
|
Opening this for review just to FYI and let people test it if they want, I will break down this PR into as many pieces as possible. |
…VMImportInterface` This patch adds the `convertInstruction` and `getSupportedInstructions` to `LLVMImportInterface`, allowing any non-LLVM dialect to specify how to import LLVM IR instructions. This patch is necessary for llvm#73057
…cies. (#86870) This patch introduces the `MemorySpaceAttrInterface` interface. This interface is responsible for handling the semantics of `ptr` operations. For example, this interface can be used to create read-only memory spaces, making any other operation other than a load a verification error, see `TestConstMemorySpaceAttr` for a possible implementation of this concept. This patch also introduces Enum dependencies `AtomicOrdering`, and `AtomicBinOp`, both enumerations are clones of the Enums with the same name in the LLVM Dialect. Also, see: - [[RFC] `ptr` dialect & modularizing ptr ops in the LLVM dialect](https://discourse.llvm.org/t/rfc-ptr-dialect-modularizing-ptr-ops-in-the-llvm-dialect/75142) for rationale. - #73057 for a prototype implementation of the full change. **Note: Ignore the first commit, that's being reviewed in #86860 .**
…nd dependencies. (#86870) This patch introduces the `MemorySpaceAttrInterface` interface. This interface is responsible for handling the semantics of `ptr` operations. For example, this interface can be used to create read-only memory spaces, making any other operation other than a load a verification error, see `TestConstMemorySpaceAttr` for a possible implementation of this concept. This patch also introduces Enum dependencies `AtomicOrdering`, and `AtomicBinOp`, both enumerations are clones of the Enums with the same name in the LLVM Dialect. Also, see: - [[RFC] `ptr` dialect & modularizing ptr ops in the LLVM dialect](https://discourse.llvm.org/t/rfc-ptr-dialect-modularizing-ptr-ops-in-the-llvm-dialect/75142) for rationale. - llvm/llvm-project#73057 for a prototype implementation of the full change. **Note: Ignore the first commit, that's being reviewed in llvm/llvm-project#86860 .**
This patch introduces the Ptr dialect, a dialect to model pointer operations motivated by the goal of modularizing the LLVM dialect.
More specifically, this patch introduces:
MemorySpaceAttrInterface
interface, an interface to conceptualize memory models, giving proper semantic meaning to the Ptr dialect ops.ptr
dialect.