forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flang] Add MALLOC and FREE intrinsics for Cray pointers (llvm#110018)
MALLOC and FREE are extensions provided by gfortran, Intel Fortran and classic flang to allocate memory for Cray pointers. These are used in some legacy codes such as libexodus. All the above compilers accept using MALLOC and FREE with integers as well, despite that this will often signify a bug in user code. We should accept the same as the other compilers for compatibility.
- Loading branch information
1 parent
4820728
commit 7caa5fa
Showing
12 changed files
with
245 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s | ||
! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s | ||
|
||
! CHECK-LABEL: func.func @_QPfree_ptr() { | ||
subroutine free_ptr() | ||
integer :: x | ||
pointer (ptr_x, x) | ||
! CHECK: %[[X:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> | ||
! CHECK: %[[X_PTR:.*]] = fir.alloca i64 {bindc_name = "ptr_x", uniq_name = "_QFfree_ptrEptr_x"} | ||
! CHECK: %[[X_PTR_DECL:.*]]:2 = hlfir.declare %[[X_PTR]] {uniq_name = "_QFfree_ptrEptr_x"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFfree_ptrEx"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) | ||
! CHECK: %[[X_LD:.*]] = fir.load %[[X_PTR_DECL]]#0 : !fir.ref<i64> | ||
! CHECK: %[[VOID:.*]] = fir.call @_FortranAFree(%[[X_LD]]) fastmath<contract> : (i64) -> none | ||
! CHECK: return | ||
call free(ptr_x) | ||
end subroutine | ||
|
||
! gfortran allows free to be used on integers, so we accept it with a warning. | ||
|
||
! CHECK-LABEL: func.func @_QPfree_i8() { | ||
subroutine free_i8 | ||
integer (kind=1) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i8 {bindc_name = "x", uniq_name = "_QFfree_i8Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFfree_i8Ex"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>) | ||
! CHECK: %[[X_LD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i8> | ||
! CHECK: %[[X_I64:.*]] = fir.convert %[[X_LD]] : (i8) -> i64 | ||
! CHECK: %[[VOID:.*]] = fir.call @_FortranAFree(%[[X_I64]]) fastmath<contract> : (i64) -> none | ||
! CHECK: return | ||
call free(x) | ||
end subroutine | ||
|
||
|
||
! CHECK-LABEL: func.func @_QPfree_i16() { | ||
subroutine free_i16 | ||
integer (kind=2) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i16 {bindc_name = "x", uniq_name = "_QFfree_i16Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFfree_i16Ex"} : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>) | ||
! CHECK: %[[X_LD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i16> | ||
! CHECK: %[[X_I64:.*]] = fir.convert %[[X_LD]] : (i16) -> i64 | ||
! CHECK: %[[VOID:.*]] = fir.call @_FortranAFree(%[[X_I64]]) fastmath<contract> : (i64) -> none | ||
! CHECK: return | ||
call free(x) | ||
end subroutine | ||
|
||
! CHECK-LABEL: func.func @_QPfree_i32() { | ||
subroutine free_i32 | ||
integer (kind=4) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFfree_i32Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFfree_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) | ||
! CHECK: %[[X_LD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i32> | ||
! CHECK: %[[X_I64:.*]] = fir.convert %[[X_LD]] : (i32) -> i64 | ||
! CHECK: %[[VOID:.*]] = fir.call @_FortranAFree(%[[X_I64]]) fastmath<contract> : (i64) -> none | ||
! CHECK: return | ||
call free(x) | ||
end subroutine | ||
|
||
! CHECK-LABEL: func.func @_QPfree_i64() { | ||
subroutine free_i64 | ||
integer (kind=8) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i64 {bindc_name = "x", uniq_name = "_QFfree_i64Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFfree_i64Ex"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) | ||
! CHECK: %[[X_LD:.*]] = fir.load %[[X_DECL]]#0 : !fir.ref<i64> | ||
! CHECK: %[[VOID:.*]] = fir.call @_FortranAFree(%[[X_LD]]) fastmath<contract> : (i64) -> none | ||
! CHECK: return | ||
call free(x) | ||
end subroutine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s | ||
! RUN: %flang_fc1 -emit-hlfir %s -o - | FileCheck %s | ||
|
||
! CHECK-LABEL: func.func @_QPmalloc_ptr() { | ||
subroutine malloc_ptr() | ||
integer :: x | ||
pointer (ptr_x, x) | ||
! CHECK: %[[X:.*]] = fir.alloca !fir.box<!fir.ptr<i32>> | ||
! CHECK: %[[X_PTR:.*]] = fir.alloca i64 {bindc_name = "ptr_x", uniq_name = "_QFmalloc_ptrEptr_x"} | ||
! CHECK: %[[X_PTR_DECL:.*]]:2 = hlfir.declare %[[X_PTR]] {uniq_name = "_QFmalloc_ptrEptr_x"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) | ||
! CHECK: %[[CST:.*]] = arith.constant 4 : i32 | ||
! CHECK: %[[CST_I64:.*]] = fir.convert %[[CST]] : (i32) -> i64 | ||
! CHECK: %[[ALLOC:.*]] = fir.call @_FortranAMalloc(%[[CST_I64]]) fastmath<contract> : (i64) -> i64 | ||
! CHECK: hlfir.assign %[[ALLOC]] to %[[X_PTR_DECL]]#0 : i64, !fir.ref<i64> | ||
! CHECK: return | ||
ptr_x = malloc(4) | ||
end subroutine | ||
|
||
! gfortran allows malloc to be assigned to integers, so we accept it. | ||
|
||
! CHECK-LABEL: func.func @_QPmalloc_i8() { | ||
subroutine malloc_i8() | ||
integer(kind=1) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i8 {bindc_name = "x", uniq_name = "_QFmalloc_i8Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFmalloc_i8Ex"} : (!fir.ref<i8>) -> (!fir.ref<i8>, !fir.ref<i8>) | ||
! CHECK: %[[CST:.*]] = arith.constant 1 : i32 | ||
! CHECK: %[[CST_I64:.*]] = fir.convert %[[CST]] : (i32) -> i64 | ||
! CHECK: %[[ALLOC:.*]] = fir.call @_FortranAMalloc(%[[CST_I64]]) fastmath<contract> : (i64) -> i64 | ||
! CHECK: %[[ALLOC_I8:.*]] = fir.convert %[[ALLOC]] : (i64) -> i8 | ||
! CHECK: hlfir.assign %[[ALLOC_I8]] to %[[X_DECL]]#0 : i8, !fir.ref<i8> | ||
! CHECK: return | ||
x = malloc(1) | ||
end subroutine | ||
|
||
! CHECK-LABEL: func.func @_QPmalloc_i16() { | ||
subroutine malloc_i16() | ||
integer(kind=2) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i16 {bindc_name = "x", uniq_name = "_QFmalloc_i16Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFmalloc_i16Ex"} : (!fir.ref<i16>) -> (!fir.ref<i16>, !fir.ref<i16>) | ||
! CHECK: %[[CST:.*]] = arith.constant 1 : i32 | ||
! CHECK: %[[CST_I64:.*]] = fir.convert %[[CST]] : (i32) -> i64 | ||
! CHECK: %[[ALLOC:.*]] = fir.call @_FortranAMalloc(%[[CST_I64]]) fastmath<contract> : (i64) -> i64 | ||
! CHECK: %[[ALLOC_I16:.*]] = fir.convert %[[ALLOC]] : (i64) -> i16 | ||
! CHECK: hlfir.assign %[[ALLOC_I16]] to %[[X_DECL]]#0 : i16, !fir.ref<i16> | ||
! CHECK: return | ||
x = malloc(1) | ||
end subroutine | ||
|
||
|
||
! CHECK-LABEL: func.func @_QPmalloc_i32() { | ||
subroutine malloc_i32() | ||
integer(kind=4) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i32 {bindc_name = "x", uniq_name = "_QFmalloc_i32Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFmalloc_i32Ex"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>) | ||
! CHECK: %[[CST:.*]] = arith.constant 1 : i32 | ||
! CHECK: %[[CST_I64:.*]] = fir.convert %[[CST]] : (i32) -> i64 | ||
! CHECK: %[[ALLOC:.*]] = fir.call @_FortranAMalloc(%[[CST_I64]]) fastmath<contract> : (i64) -> i64 | ||
! CHECK: %[[ALLOC_I32:.*]] = fir.convert %[[ALLOC]] : (i64) -> i32 | ||
! CHECK: hlfir.assign %[[ALLOC_I32]] to %[[X_DECL]]#0 : i32, !fir.ref<i32> | ||
! CHECK: return | ||
x = malloc(1) | ||
end subroutine | ||
|
||
! CHECK-LABEL: func.func @_QPmalloc_i64() { | ||
subroutine malloc_i64() | ||
integer(kind=8) :: x | ||
! CHECK: %[[X:.*]] = fir.alloca i64 {bindc_name = "x", uniq_name = "_QFmalloc_i64Ex"} | ||
! CHECK: %[[X_DECL:.*]]:2 = hlfir.declare %[[X]] {uniq_name = "_QFmalloc_i64Ex"} : (!fir.ref<i64>) -> (!fir.ref<i64>, !fir.ref<i64>) | ||
! CHECK: %[[CST:.*]] = arith.constant 1 : i32 | ||
! CHECK: %[[CST_I64:.*]] = fir.convert %[[CST]] : (i32) -> i64 | ||
! CHECK: %[[ALLOC:.*]] = fir.call @_FortranAMalloc(%[[CST_I64]]) fastmath<contract> : (i64) -> i64 | ||
! CHECK: hlfir.assign %[[ALLOC]] to %[[X_DECL]]#0 : i64, !fir.ref<i64> | ||
! CHECK: return | ||
x = malloc(1) | ||
end subroutine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
! RUN: %python %S/test_errors.py %s %flang_fc1 -Werror | ||
|
||
! Accept free of cray pointer without warning | ||
subroutine free_cptr() | ||
integer :: x | ||
pointer(ptr_x, x) | ||
call free(ptr_x) | ||
end subroutine | ||
|
||
subroutine free_i8() | ||
integer(kind=1) :: x | ||
! WARNING: FREE should only be used with Cray pointers | ||
call free(x) | ||
end subroutine | ||
|
||
|
||
subroutine free_i16() | ||
integer(kind=2) :: x | ||
! WARNING: FREE should only be used with Cray pointers | ||
call free(x) | ||
end subroutine | ||
|
||
subroutine free_i32() | ||
integer(kind=4) :: x | ||
! WARNING: FREE should only be used with Cray pointers | ||
call free(x) | ||
end subroutine | ||
|
||
subroutine free_i64() | ||
integer(kind=8) :: x | ||
! WARNING: FREE should only be used with Cray pointers | ||
call free(x) | ||
end subroutine |