Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -780,11 +780,14 @@ static ParseResult parseVarPtrType(mlir::OpAsmParser &parser,
return failure();
} else {
// Set `varType` from the element type of the type of `varPtr`.
if (mlir::isa<mlir::acc::PointerLikeType>(varPtrType))
varTypeAttr = mlir::TypeAttr::get(
mlir::cast<mlir::acc::PointerLikeType>(varPtrType).getElementType());
else
if (auto ptrTy = dyn_cast<acc::PointerLikeType>(varPtrType)) {
Type elementType = ptrTy.getElementType();
// Opaque pointers (e.g. !llvm.ptr) have no element type; fall back to
// using varPtrType itself so that the attribute is always valid.
varTypeAttr = mlir::TypeAttr::get(elementType ? elementType : varPtrType);
} else {
varTypeAttr = mlir::TypeAttr::get(varPtrType);
}
}

return success();
Expand All @@ -802,6 +805,10 @@ static void printVarPtrType(mlir::OpAsmPrinter &p, mlir::Operation *op,
mlir::isa<mlir::acc::PointerLikeType>(varPtrType)
? mlir::cast<mlir::acc::PointerLikeType>(varPtrType).getElementType()
: varPtrType;
// Opaque pointers (e.g. !llvm.ptr) have no element type; use varPtrType as
// the baseline so that the inferred varType is not redundantly printed.
if (!typeToCheckAgainst)
typeToCheckAgainst = varPtrType;
if (typeToCheckAgainst != varType) {
p << " varType(";
p.printType(varType);
Expand Down
18 changes: 18 additions & 0 deletions mlir/test/Dialect/OpenACC/ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -2504,3 +2504,21 @@ func.func @test_acc_reduction_combine(%arg0 : memref<i32>, %arg1 : memref<i32>)

// CHECK-LABEL: func @test_acc_reduction_combine
// CHECK: acc.reduction_combine %arg0 into %arg1 <add> : memref<i32>

// -----

// Test that acc.getdeviceptr with an opaque pointer (!llvm.ptr, which has no
// element type) can be parsed and printed without an explicit varType clause.
// This is a regression test for a crash where getElementType() returned null
// for opaque pointers and was passed to TypeAttr::get() without a null check.

func.func @test_getdeviceptr_opaque_ptr(%a: !llvm.ptr) -> () {
%0 = acc.getdeviceptr varPtr(%a : !llvm.ptr) -> !llvm.ptr
acc.declare_enter dataOperands(%0 : !llvm.ptr)
return
}

// CHECK-LABEL: func @test_getdeviceptr_opaque_ptr(
// CHECK-SAME: %[[A:.*]]: !llvm.ptr)
// CHECK: %[[DEVPTR:.*]] = acc.getdeviceptr varPtr(%[[A]] : !llvm.ptr) -> !llvm.ptr
// CHECK: acc.declare_enter dataOperands(%[[DEVPTR]] : !llvm.ptr)