Skip to content

Commit 15788e8

Browse files
authored
[flang] Lower c_ptr_eq/ne for iso_c_binding (#85135)
Comparing c_ptr type for equality or inequality is raising an error. ``` not yet implemented: intrinsic module procedure: c_ptr_eq ``` or this one for inequality ``` not yet implemented: intrinsic module procedure: c_ptr_ne ``` This patch adds a lowering for them and fix the `__fortran_builtins.f90` module for inequality.
1 parent d92d2e2 commit 15788e8

File tree

4 files changed

+79
-1
lines changed

4 files changed

+79
-1
lines changed

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ struct IntrinsicLibrary {
208208
void genCFProcPointer(llvm::ArrayRef<fir::ExtendedValue>);
209209
fir::ExtendedValue genCFunLoc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
210210
fir::ExtendedValue genCLoc(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
211+
template <mlir::arith::CmpIPredicate pred>
212+
fir::ExtendedValue genCPtrCompare(mlir::Type,
213+
llvm::ArrayRef<fir::ExtendedValue>);
211214
mlir::Value genCosd(mlir::Type, llvm::ArrayRef<mlir::Value>);
212215
void genDateAndTime(llvm::ArrayRef<fir::ExtendedValue>);
213216
mlir::Value genDim(mlir::Type, llvm::ArrayRef<mlir::Value>);

flang/lib/Optimizer/Builder/IntrinsicCall.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ static constexpr IntrinsicHandler handlers[]{
177177
/*isElemental=*/false},
178178
{"c_funloc", &I::genCFunLoc, {{{"x", asBox}}}, /*isElemental=*/false},
179179
{"c_loc", &I::genCLoc, {{{"x", asBox}}}, /*isElemental=*/false},
180+
{"c_ptr_eq", &I::genCPtrCompare<mlir::arith::CmpIPredicate::eq>},
181+
{"c_ptr_ne", &I::genCPtrCompare<mlir::arith::CmpIPredicate::ne>},
180182
{"ceiling", &I::genCeiling},
181183
{"char", &I::genChar},
182184
{"cmplx",
@@ -2797,6 +2799,23 @@ IntrinsicLibrary::genCLoc(mlir::Type resultType,
27972799
return genCLocOrCFunLoc(builder, loc, resultType, args);
27982800
}
27992801

2802+
// C_PTR_EQ and C_PTR_NE
2803+
template <mlir::arith::CmpIPredicate pred>
2804+
fir::ExtendedValue
2805+
IntrinsicLibrary::genCPtrCompare(mlir::Type resultType,
2806+
llvm::ArrayRef<fir::ExtendedValue> args) {
2807+
assert(args.size() == 2);
2808+
mlir::Value cPtr1 = fir::getBase(args[0]);
2809+
mlir::Value cPtrVal1 =
2810+
fir::factory::genCPtrOrCFunptrValue(builder, loc, cPtr1);
2811+
mlir::Value cPtr2 = fir::getBase(args[1]);
2812+
mlir::Value cPtrVal2 =
2813+
fir::factory::genCPtrOrCFunptrValue(builder, loc, cPtr2);
2814+
mlir::Value cmp =
2815+
builder.create<mlir::arith::CmpIOp>(loc, pred, cPtrVal1, cPtrVal2);
2816+
return builder.createConvert(loc, resultType, cmp);
2817+
}
2818+
28002819
// CEILING
28012820
mlir::Value IntrinsicLibrary::genCeiling(mlir::Type resultType,
28022821
llvm::ArrayRef<mlir::Value> args) {

flang/module/__fortran_builtins.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
public :: operator(==)
111111

112112
interface operator(/=)
113-
module procedure __builtin_c_ptr_eq
113+
module procedure __builtin_c_ptr_ne
114114
end interface
115115
public :: operator(/=)
116116

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
! Test C_PTR_EQ and C_PTR_NE lowering.
2+
! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
3+
4+
function test_c_ptr_eq(ptr1, ptr2)
5+
use, intrinsic :: iso_c_binding
6+
type(c_ptr), intent(in) :: ptr1, ptr2
7+
logical :: test_c_ptr_eq
8+
test_c_ptr_eq = (ptr1 .eq. ptr2)
9+
end
10+
11+
! CHECK-LABEL: func.func @_QPtest_c_ptr_eq(
12+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "ptr1"}, %[[ARG1:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "ptr2"}) -> !fir.logical<4> {
13+
! CHECK: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest_c_ptr_eqEptr1"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
14+
! CHECK: %[[DECL_ARG1:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest_c_ptr_eqEptr2"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
15+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> {bindc_name = "test_c_ptr_eq", uniq_name = "_QFtest_c_ptr_eqEtest_c_ptr_eq"}
16+
! CHECK: %[[DECL_RET:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "_QFtest_c_ptr_eqEtest_c_ptr_eq"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
17+
! CHECK: %[[FIELD_ADDRESS:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
18+
! CHECK: %[[COORD_ADDRESS0:.*]] = fir.coordinate_of %[[DECL_ARG0]]#1, %[[FIELD_ADDRESS]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
19+
! CHECK: %[[ADDRESS0:.*]] = fir.load %[[COORD_ADDRESS0]] : !fir.ref<i64>
20+
! CHECK: %[[FIELD_ADDRESS:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
21+
! CHECK: %[[COORD_ADDRESS1:.*]] = fir.coordinate_of %[[DECL_ARG1]]#1, %[[FIELD_ADDRESS]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
22+
! CHECK: %[[ADDRESS1:.*]] = fir.load %[[COORD_ADDRESS1]] : !fir.ref<i64>
23+
! CHECK: %[[CMP:.*]] = arith.cmpi eq, %[[ADDRESS0]], %[[ADDRESS1]] : i64
24+
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
25+
! CHECK: %[[NO_REASSOC_RES:.*]] = hlfir.no_reassoc %[[RES]] : !fir.logical<4>
26+
! CHECK: hlfir.assign %[[NO_REASSOC_RES]] to %[[DECL_RET]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
27+
! CHECK: %[[LOAD_RET:.*]] = fir.load %[[DECL_RET]]#1 : !fir.ref<!fir.logical<4>>
28+
! CHECK: return %[[LOAD_RET]] : !fir.logical<4>
29+
! CHECK: }
30+
31+
function test_c_ptr_ne(ptr1, ptr2)
32+
use, intrinsic :: iso_c_binding
33+
type(c_ptr), intent(in) :: ptr1, ptr2
34+
logical :: test_c_ptr_ne
35+
test_c_ptr_ne = (ptr1 .ne. ptr2)
36+
end
37+
38+
! CHECK-LABEL: func.func @_QPtest_c_ptr_ne(
39+
! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "ptr1"}, %[[ARG1:.*]]: !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>> {fir.bindc_name = "ptr2"}) -> !fir.logical<4> {
40+
! CHECK: %[[DECL_ARG0:.*]]:2 = hlfir.declare %[[ARG0]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest_c_ptr_neEptr1"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
41+
! CHECK: %[[DECL_ARG1:.*]]:2 = hlfir.declare %[[ARG1]] {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFtest_c_ptr_neEptr2"} : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>)
42+
! CHECK: %[[ALLOCA:.*]] = fir.alloca !fir.logical<4> {bindc_name = "test_c_ptr_ne", uniq_name = "_QFtest_c_ptr_neEtest_c_ptr_ne"}
43+
! CHECK: %[[DECL_RET:.*]]:2 = hlfir.declare %[[ALLOCA]] {uniq_name = "_QFtest_c_ptr_neEtest_c_ptr_ne"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
44+
! CHECK: %[[FIELD_ADDRESS:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
45+
! CHECK: %[[COORD_ADDRESS0:.*]] = fir.coordinate_of %[[DECL_ARG0]]#1, %[[FIELD_ADDRESS]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
46+
! CHECK: %[[ADDRESS0:.*]] = fir.load %[[COORD_ADDRESS0]] : !fir.ref<i64>
47+
! CHECK: %[[FIELD_ADDRESS:.*]] = fir.field_index __address, !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
48+
! CHECK: %[[COORD_ADDRESS1:.*]] = fir.coordinate_of %[[DECL_ARG1]]#1, %[[FIELD_ADDRESS]] : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>, !fir.field) -> !fir.ref<i64>
49+
! CHECK: %[[ADDRESS1:.*]] = fir.load %[[COORD_ADDRESS1]] : !fir.ref<i64>
50+
! CHECK: %[[CMP:.*]] = arith.cmpi ne, %[[ADDRESS0]], %[[ADDRESS1]] : i64
51+
! CHECK: %[[RES:.*]] = fir.convert %[[CMP]] : (i1) -> !fir.logical<4>
52+
! CHECK: %[[NO_REASSOC_RES:.*]] = hlfir.no_reassoc %[[RES]] : !fir.logical<4>
53+
! CHECK: hlfir.assign %[[NO_REASSOC_RES]] to %[[DECL_RET]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
54+
! CHECK: %[[LOAD_RET:.*]] = fir.load %[[DECL_RET]]#1 : !fir.ref<!fir.logical<4>>
55+
! CHECK: return %[[LOAD_RET]] : !fir.logical<4>
56+
! CHECK: }

0 commit comments

Comments
 (0)