Skip to content

Commit d7d9150

Browse files
[flang][nfc] Initial changes needed to use llvm intrinsics instead of regular calls (#134170)
Flang uses `fir.call <llvm intrinsic>` in a few places. This means consumers of the IR need to strcmp every fir.call if they want to find a particular LLVM intrinsic. Emit LLVM memcpy intrinsics instead.
1 parent 49fd0bf commit d7d9150

File tree

4 files changed

+18
-34
lines changed

4 files changed

+18
-34
lines changed

Diff for: flang/include/flang/Optimizer/Builder/LowLevelIntrinsics.h

-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ class FirOpBuilder;
2424

2525
namespace fir::factory {
2626

27-
/// Get the LLVM intrinsic for `memcpy`. Use the 64 bit version.
28-
mlir::func::FuncOp getLlvmMemcpy(FirOpBuilder &builder);
29-
3027
/// Get the LLVM intrinsic for `memmove`. Use the 64 bit version.
3128
mlir::func::FuncOp getLlvmMemmove(FirOpBuilder &builder);
3229

Diff for: flang/lib/Lower/ConvertExpr.cpp

+10-13
Original file line numberDiff line numberDiff line change
@@ -6184,17 +6184,16 @@ class ArrayExprLowering {
61846184

61856185
/// Get the function signature of the LLVM memcpy intrinsic.
61866186
mlir::FunctionType memcpyType() {
6187-
return fir::factory::getLlvmMemcpy(builder).getFunctionType();
6187+
auto ptrTy = mlir::LLVM::LLVMPointerType::get(builder.getContext());
6188+
llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type()};
6189+
return mlir::FunctionType::get(builder.getContext(), args, std::nullopt);
61886190
}
61896191

61906192
/// Create a call to the LLVM memcpy intrinsic.
6191-
void createCallMemcpy(llvm::ArrayRef<mlir::Value> args) {
6193+
void createCallMemcpy(llvm::ArrayRef<mlir::Value> args, bool isVolatile) {
61926194
mlir::Location loc = getLoc();
6193-
mlir::func::FuncOp memcpyFunc = fir::factory::getLlvmMemcpy(builder);
6194-
mlir::SymbolRefAttr funcSymAttr =
6195-
builder.getSymbolRefAttr(memcpyFunc.getName());
6196-
mlir::FunctionType funcTy = memcpyFunc.getFunctionType();
6197-
builder.create<fir::CallOp>(loc, funcSymAttr, funcTy.getResults(), args);
6195+
builder.create<mlir::LLVM::MemcpyOp>(loc, args[0], args[1], args[2],
6196+
isVolatile);
61986197
}
61996198

62006199
// Construct code to check for a buffer overrun and realloc the buffer when
@@ -6306,9 +6305,8 @@ class ArrayExprLowering {
63066305
auto buff = builder.createConvert(loc, fir::HeapType::get(resTy), mem);
63076306
mlir::Value buffi = computeCoordinate(buff, off);
63086307
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
6309-
builder, loc, memcpyType(), buffi, v.getAddr(), byteSz,
6310-
/*volatile=*/builder.createBool(loc, false));
6311-
createCallMemcpy(args);
6308+
builder, loc, memcpyType(), buffi, v.getAddr(), byteSz);
6309+
createCallMemcpy(args, /*isVolatile=*/false);
63126310

63136311
// Save the incremented buffer position.
63146312
builder.create<fir::StoreOp>(loc, endOff, buffPos);
@@ -6357,9 +6355,8 @@ class ArrayExprLowering {
63576355
builder.createConvert(loc, fir::HeapType::get(resTy), mem);
63586356
mlir::Value buffi = computeCoordinate(buff, off);
63596357
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
6360-
builder, loc, memcpyType(), buffi, v.getAddr(), eleSz,
6361-
/*volatile=*/builder.createBool(loc, false));
6362-
createCallMemcpy(args);
6358+
builder, loc, memcpyType(), buffi, v.getAddr(), eleSz);
6359+
createCallMemcpy(args, /*isVolatile=*/false);
63636360

63646361
builder.create<fir::StoreOp>(loc, plusOne, buffPos);
63656362
}

Diff for: flang/lib/Optimizer/Builder/LowLevelIntrinsics.cpp

-10
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,6 @@
2121
#include "flang/Optimizer/Builder/LowLevelIntrinsics.h"
2222
#include "flang/Optimizer/Builder/FIRBuilder.h"
2323

24-
mlir::func::FuncOp fir::factory::getLlvmMemcpy(fir::FirOpBuilder &builder) {
25-
auto ptrTy = builder.getRefType(builder.getIntegerType(8));
26-
llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type(),
27-
builder.getI1Type()};
28-
auto memcpyTy =
29-
mlir::FunctionType::get(builder.getContext(), args, std::nullopt);
30-
return builder.createFunction(builder.getUnknownLoc(),
31-
"llvm.memcpy.p0.p0.i64", memcpyTy);
32-
}
33-
3424
mlir::func::FuncOp fir::factory::getLlvmMemmove(fir::FirOpBuilder &builder) {
3525
auto ptrTy = builder.getRefType(builder.getIntegerType(8));
3626
llvm::SmallVector<mlir::Type> args = {ptrTy, ptrTy, builder.getI64Type(),

Diff for: flang/test/Lower/array-constructor-2.f90

+8-8
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ end function test3c
7878
! CHECK-DAG: %[[rep:.*]] = fir.convert %{{.*}} : (!fir.heap<f32>) -> !fir.ref<i8>
7979
! CHECK-DAG: %[[res:.*]] = fir.convert %{{.*}} : (index) -> i64
8080
! CHECK: %{{.*}} = fir.call @realloc(%[[rep]], %[[res]]) {{.*}}: (!fir.ref<i8>, i64) -> !fir.ref<i8>
81-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
81+
! CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
8282
! CHECK: fir.call @_QPtest3c
8383
! CHECK: fir.save_result
8484
! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array<?xf32>, %{{.*}}#1 {uniq_name = ".array.expr"}
8585
! CHECK: fir.call @realloc
86-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%
86+
! CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
8787
! CHECK: fir.array_coor %[[tmp:.*]](%{{.*}}) %{{.*}} : (!fir.heap<!fir.array<?xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
8888
! CHECK-NEXT: fir.load
8989
! CHECK-NEXT: fir.array_coor %arg0 %{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
@@ -130,11 +130,11 @@ subroutine test5(a, array2)
130130
! CHECK: %[[res:.*]] = fir.allocmem !fir.array<4xf32>
131131
! CHECK: fir.address_of(@_QQro.2xr4.2) : !fir.ref<!fir.array<2xf32>>
132132
! CHECK: %[[tmp1:.*]] = fir.allocmem !fir.array<2xf32>
133-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
133+
! CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
134134
! CHECK: %[[tmp2:.*]] = fir.allocmem !fir.array<2xf32>
135135
! CHECK: = fir.array_coor %[[array2]](%{{.*}}) %{{.*}} : (!fir.ref<!fir.array<2xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
136136
! CHECK: = fir.array_coor %[[tmp2]](%{{.*}}) %{{.*}} : (!fir.heap<!fir.array<2xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
137-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%{{.*}}, %{{.*}}, %{{.*}}, %false{{.*}}) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
137+
! CHECK: "llvm.intr.memcpy"(%{{.*}}, %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
138138
! CHECK: = fir.array_coor %{{.*}}(%{{.*}}) %{{.*}} : (!fir.heap<!fir.array<4xf32>>, !fir.shape<1>, index) -> !fir.ref<f32>
139139
! CHECK: = fir.array_coor %[[a]] %{{.*}} : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32>
140140
! CHECK-DAG: fir.freemem %{{.*}} : !fir.heap<!fir.array<4xf32>>
@@ -151,12 +151,12 @@ subroutine test6(c, d, e)
151151
! CHECK: = fir.allocmem !fir.array<2x!fir.char<1,5>>
152152
! CHECK: fir.call @realloc
153153
! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap<!fir.array<2x!fir.char<1,5>>>, index) -> !fir.ref<!fir.char<1,5>>
154-
! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<i8>
155-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%[[to]], %{{.*}}, %{{.*}}, %false) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
154+
! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref<!fir.char<1,5>>) -> !llvm.ptr
155+
! CHECK: "llvm.intr.memcpy"(%[[to]], %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
156156
! CHECK: fir.call @realloc
157157
! CHECK: %[[t:.*]] = fir.coordinate_of %{{.*}}, %{{.*}} : (!fir.heap<!fir.array<2x!fir.char<1,5>>>, index) -> !fir.ref<!fir.char<1,5>>
158-
! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref<!fir.char<1,5>>) -> !fir.ref<i8>
159-
! CHECK: fir.call @llvm.memcpy.p0.p0.i64(%[[to]], %{{.*}}, %{{.*}}, %false) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
158+
! CHECK: %[[to:.*]] = fir.convert %[[t]] : (!fir.ref<!fir.char<1,5>>) -> !llvm.ptr
159+
! CHECK: "llvm.intr.memcpy"(%[[to]], %{{.*}}, %{{.*}}) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
160160
! CHECK: fir.freemem %{{.*}} : !fir.heap<!fir.array<2x!fir.char<1,5>>>
161161
c = (/ d, e /)
162162
end subroutine test6

0 commit comments

Comments
 (0)