llvm-project/mlir/test/Dialect/LLVMIR/opaque-ptr.mlir
Alex Zinenko 2366a43b3c [mlir] initial support for opaque pointers in the LLVM dialect
LLVM IR has introduced and is moving forward with the concept of opaque
pointers, i.e. pointer types that are not carrying around the pointee type.
Instead, memory-related operations indicate the type of the data being accessed
through the opaque pointer. Introduce the initial support for opaque pointers
in the LLVM dialect:

  - `LLVMPointerType` to support omitting the element type;
  - alloca/load/store/gep to support opaque pointers in their operands and
    results; this requires alloca and gep to store the element type as an
    attribute;
  - memory-related intrinsics to support opaque pointers in their operands;
  - translation to LLVM IR for the ops above is no longer using methods
    deprecated in LLVM API due to the introduction of opaque pointers.

Unlike LLVM IR, MLIR can afford to support both opaque and non-opaque pointers
at the same time and simplify the transition. Translation to LLVM IR of MLIR
that involves opaque pointers requires the LLVMContext to be configured to
always use opaque pointers.

Reviewed By: wsmoses

Differential Revision: https://reviews.llvm.org/D123310
2022-04-14 13:23:29 +02:00

78 lines
3.1 KiB
MLIR

// RUN: mlir-opt %s | mlir-opt | FileCheck %s
// CHECK-LABEL: @opaque_ptr_load
llvm.func @opaque_ptr_load(%arg0: !llvm.ptr) -> i32 {
// CHECK: = llvm.load %{{.*}} : !llvm.ptr -> i32
%0 = llvm.load %arg0 : !llvm.ptr -> i32
llvm.return %0 : i32
}
// CHECK-LABEL: @opaque_ptr_store
llvm.func @opaque_ptr_store(%arg0: i32, %arg1: !llvm.ptr){
// CHECK: llvm.store %{{.*}}, %{{.*}} : i32, !llvm.ptr
llvm.store %arg0, %arg1 : i32, !llvm.ptr
llvm.return
}
// CHECK-LABEL: @opaque_ptr_ptr_store
llvm.func @opaque_ptr_ptr_store(%arg0: !llvm.ptr, %arg1: !llvm.ptr) {
// CHECK: llvm.store %{{.*}}, %{{.*}} : !llvm.ptr, !llvm.ptr
llvm.store %arg0, %arg1 : !llvm.ptr, !llvm.ptr
llvm.return
}
// CHECK-LABEL: @opaque_ptr_alloca
llvm.func @opaque_ptr_alloca(%arg0: i32) -> !llvm.ptr {
// CHECK: llvm.alloca %{{.*}} x f32 : (i32) -> !llvm.ptr
%0 = llvm.alloca %arg0 x f32 : (i32) -> !llvm.ptr
llvm.return %0 : !llvm.ptr
}
// CHECK-LABEL: @opaque_ptr_gep
llvm.func @opaque_ptr_gep(%arg0: !llvm.ptr, %arg1: i32) -> !llvm.ptr {
// CHECK: = llvm.getelementptr %{{.*}}[%{{.*}}] : (!llvm.ptr, i32) -> !llvm.ptr, f32
%0 = llvm.getelementptr %arg0[%arg1] : (!llvm.ptr, i32) -> !llvm.ptr, f32
llvm.return %0 : !llvm.ptr
}
// CHECK-LABEL: @opaque_ptr_gep_struct
llvm.func @opaque_ptr_gep_struct(%arg0: !llvm.ptr, %arg1: i32) -> !llvm.ptr {
// CHECK: = llvm.getelementptr %{{.*}}[%{{.*}}, 0, 1]
// CHECK: : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(struct<(f32, f64)>, struct<(i32, i64)>)>
%0 = llvm.getelementptr %arg0[%arg1, 0, 1] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(struct<(f32, f64)>, struct<(i32, i64)>)>
llvm.return %0 : !llvm.ptr
}
// CHECK-LABEL: @opaque_ptr_matrix_load_store
llvm.func @opaque_ptr_matrix_load_store(%ptr: !llvm.ptr, %stride: i64) -> vector<48 x f32> {
// CHECK: = llvm.intr.matrix.column.major.load
// CHECK: vector<48xf32> from !llvm.ptr stride i64
%0 = llvm.intr.matrix.column.major.load %ptr, <stride=%stride>
{ isVolatile = 0: i1, rows = 3: i32, columns = 16: i32} :
vector<48 x f32> from !llvm.ptr stride i64
// CHECK: llvm.intr.matrix.column.major.store
// CHECK: vector<48xf32> to !llvm.ptr stride i64
llvm.intr.matrix.column.major.store %0, %ptr, <stride=%stride>
{ isVolatile = 0: i1, rows = 3: i32, columns = 16: i32} :
vector<48 x f32> to !llvm.ptr stride i64
llvm.return %0 : vector<48 x f32>
}
// CHECK-LABEL: @opaque_ptr_masked_load
llvm.func @opaque_ptr_masked_load(%arg0: !llvm.ptr, %arg1: vector<7xi1>) -> vector<7xf32> {
// CHECK: = llvm.intr.masked.load
// CHECK: (!llvm.ptr, vector<7xi1>) -> vector<7xf32>
%0 = llvm.intr.masked.load %arg0, %arg1 { alignment = 1: i32} :
(!llvm.ptr, vector<7xi1>) -> vector<7xf32>
llvm.return %0 : vector<7 x f32>
}
// CHECK-LABEL: @opaque_ptr_gather
llvm.func @opaque_ptr_gather(%M: !llvm.vec<7 x ptr>, %mask: vector<7xi1>) -> vector<7xf32> {
// CHECK: = llvm.intr.masked.gather
// CHECK: (!llvm.vec<7 x ptr>, vector<7xi1>) -> vector<7xf32>
%a = llvm.intr.masked.gather %M, %mask { alignment = 1: i32} :
(!llvm.vec<7 x ptr>, vector<7xi1>) -> vector<7xf32>
llvm.return %a : vector<7xf32>
}