Skip to content

Commit 85fd83e

Browse files
[flang][nfc] Use llvm memmove intrinsic over regular call (#134294)
Follow up to #134170. We should be using the LLVM intrinsics instead of plain fir.calls when we can. Existing code creates a declaration for the llvm intrinsic and a regular fir.call, which makes it hard for consumers of the IR to find all the intrinsic calls.
1 parent d2bcc11 commit 85fd83e

12 files changed

+315
-327
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 `memmove`. Use the 64 bit version.
28-
mlir::func::FuncOp getLlvmMemmove(FirOpBuilder &builder);
29-
3027
/// Get the LLVM intrinsic for `memset`. Use the 64 bit version.
3128
mlir::func::FuncOp getLlvmMemset(FirOpBuilder &builder);
3229

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "flang/Optimizer/Builder/FIRBuilder.h"
1616
#include "flang/Optimizer/Builder/Todo.h"
1717
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
18+
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
1819
#include "llvm/Support/Debug.h"
1920
#include <optional>
2021

@@ -335,13 +336,12 @@ void fir::factory::CharacterExprHelper::createCopy(
335336
auto castCount = builder.createConvert(loc, i64Ty, count);
336337
auto totalBytes =
337338
builder.create<mlir::arith::MulIOp>(loc, kindBytes, castCount);
338-
auto notVolatile = builder.createBool(loc, false);
339-
auto memmv = getLlvmMemmove(builder);
340-
auto argTys = memmv.getFunctionType().getInputs();
341-
auto toPtr = builder.createConvert(loc, argTys[0], toBuff);
342-
auto fromPtr = builder.createConvert(loc, argTys[1], fromBuff);
343-
builder.create<fir::CallOp>(
344-
loc, memmv, mlir::ValueRange{toPtr, fromPtr, totalBytes, notVolatile});
339+
auto llvmPointerType =
340+
mlir::LLVM::LLVMPointerType::get(builder.getContext());
341+
auto toPtr = builder.createConvert(loc, llvmPointerType, toBuff);
342+
auto fromPtr = builder.createConvert(loc, llvmPointerType, fromBuff);
343+
builder.create<mlir::LLVM::MemmoveOp>(loc, toPtr, fromPtr, totalBytes,
344+
/*isVolatile=*/false);
345345
return;
346346
}
347347

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::getLlvmMemmove(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 memmoveTy =
29-
mlir::FunctionType::get(builder.getContext(), args, std::nullopt);
30-
return builder.createFunction(builder.getUnknownLoc(),
31-
"llvm.memmove.p0.p0.i64", memmoveTy);
32-
}
33-
3424
mlir::func::FuncOp fir::factory::getLlvmMemset(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/HLFIR/assign-codegen.fir

+4-5
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,9 @@ func.func @scalar_character(%arg0: !fir.boxchar<1>, %arg1: !fir.boxchar<1>) {
104104
// CHECK: %[[VAL_10:.*]] = arith.constant 1 : i64
105105
// CHECK: %[[VAL_11:.*]] = fir.convert %[[VAL_9]] : (index) -> i64
106106
// CHECK: %[[VAL_12:.*]] = arith.muli %[[VAL_10]], %[[VAL_11]] : i64
107-
// CHECK: %[[VAL_13:.*]] = arith.constant false
108-
// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
109-
// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
110-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_14]], %[[VAL_15]], %[[VAL_12]], %[[VAL_13]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
107+
// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
108+
// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_6]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
109+
// CHECK: "llvm.intr.memmove"(%[[VAL_14]], %[[VAL_15]], %[[VAL_12]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
111110
// CHECK: %[[VAL_16:.*]] = arith.constant 1 : index
112111
// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_2]]#1, %[[VAL_16]] : index
113112
// CHECK: %[[VAL_18:.*]] = arith.constant 32 : i8
@@ -480,4 +479,4 @@ func.func @test_scalar_opt_char_box(%arg0: !fir.ref<!fir.char<1,10>>, %arg1: !fi
480479
// CHECK: fir.result %[[VAL_8]], %[[VAL_9]] : !fir.ref<!fir.char<1,?>>, index
481480
// CHECK: }
482481
// ...
483-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(
482+
// CHECK: "llvm.intr.memmove"

Diff for: flang/test/HLFIR/associate-codegen.fir

+3-4
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,9 @@ func.func @associate_char(%arg0: !fir.boxchar<1> ) {
8080
// CHECK: %[[VAL_9:.*]] = arith.constant 1 : i64
8181
// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_2]]#1 : (index) -> i64
8282
// CHECK: %[[VAL_11:.*]] = arith.muli %[[VAL_9]], %[[VAL_10]] : i64
83-
// CHECK: %[[VAL_12:.*]] = arith.constant false
84-
// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
85-
// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
86-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_13]], %[[VAL_14]], %[[VAL_11]], %[[VAL_12]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
83+
// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_8]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
84+
// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
85+
// CHECK: "llvm.intr.memmove"(%[[VAL_13]], %[[VAL_14]], %[[VAL_11]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
8786
// CHECK: %[[VAL_15:.*]] = arith.constant 1 : index
8887
// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_7]], %[[VAL_15]] : index
8988
// CHECK: fir.do_loop %[[VAL_17:.*]] = %[[VAL_2]]#1 to %[[VAL_16]] step %[[VAL_15]] {

Diff for: flang/test/HLFIR/char_extremum-bufferization.fir

+20-25
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ func.func @_QPmax1(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
3939
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
4040
// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (index) -> i64
4141
// CHECK: %[[VAL_20:.*]] = arith.muli %[[C1_I64]], %[[VAL_19]] : i64
42-
// CHECK: %[[FALSE:.*]] = arith.constant false
43-
// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
44-
// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
45-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
42+
// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
43+
// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
44+
// CHECK: "llvm.intr.memmove"(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
4645
// CHECK: %[[C1:.*]] = arith.constant 1 : index
4746
// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_7]], %[[C1]] : index
4847
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8
@@ -76,7 +75,8 @@ func.func @_QPmin1(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
7675
return
7776
}
7877

79-
// CHECK: func.func @_QPmin1(%[[ARG0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c1"}, %[[ARG1:.*]]: !fir.boxchar<1> {fir.bindc_name = "c2"}, %[[ARG2:.*]]: !fir.boxchar<1> {fir.bindc_name = "c3"}) {
78+
// CHECK-LABEL: func.func @_QPmin1
79+
// CHECK-SAME: (%[[ARG0:.*]]: !fir.boxchar<1> {fir.bindc_name = "c1"}, %[[ARG1:.*]]: !fir.boxchar<1> {fir.bindc_name = "c2"}, %[[ARG2:.*]]: !fir.boxchar<1> {fir.bindc_name = "c3"}) {
8080
// CHECK: %[[VAL_0:.*]]:2 = fir.unboxchar %[[ARG0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
8181
// CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]]#0 typeparams %[[VAL_0]]#1 {uniq_name = "_QFmin1Ec1"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
8282
// CHECK: %[[VAL_2:.*]]:2 = fir.unboxchar %[[ARG1]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
@@ -100,10 +100,9 @@ func.func @_QPmin1(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
100100
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
101101
// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (index) -> i64
102102
// CHECK: %[[VAL_20:.*]] = arith.muli %[[C1_I64]], %[[VAL_19]] : i64
103-
// CHECK: %[[FALSE:.*]] = arith.constant false
104-
// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
105-
// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
106-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
103+
// CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_16]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
104+
// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_14]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
105+
// CHECK: "llvm.intr.memmove"(%[[VAL_21]], %[[VAL_22]], %[[VAL_20]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
107106
// CHECK: %[[C1:.*]] = arith.constant 1 : index
108107
// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_7]], %[[C1]] : index
109108
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8
@@ -195,10 +194,9 @@ func.func @_QPmax2(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
195194
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
196195
// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (index) -> i64
197196
// CHECK: %[[VAL_30:.*]] = arith.muli %[[C1_I64]], %[[VAL_29]] : i64
198-
// CHECK: %[[FALSE:.*]] = arith.constant false
199-
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
200-
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_24]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
201-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_31]], %[[VAL_32]], %[[VAL_30]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
197+
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
198+
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_24]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
199+
// CHECK: "llvm.intr.memmove"(%[[VAL_31]], %[[VAL_32]], %[[VAL_30]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
202200
// CHECK: %[[C1_3:.*]] = arith.constant 1 : index
203201
// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_15]], %[[C1_3]] : index
204202
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8
@@ -293,10 +291,9 @@ func.func @_QPmin2(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
293291
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
294292
// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (index) -> i64
295293
// CHECK: %[[VAL_30:.*]] = arith.muli %[[C1_I64]], %[[VAL_29]] : i64
296-
// CHECK: %[[FALSE:.*]] = arith.constant false
297-
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
298-
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_24]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
299-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_31]], %[[VAL_32]], %[[VAL_30]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
294+
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
295+
// CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_24]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
296+
// CHECK: "llvm.intr.memmove"(%[[VAL_31]], %[[VAL_32]], %[[VAL_30]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
300297
// CHECK: %[[C1_3:.*]] = arith.constant 1 : index
301298
// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_15]], %[[C1_3]] : index
302299
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8
@@ -372,10 +369,9 @@ func.func @_QPmax3(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
372369
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
373370
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
374371
// CHECK: %[[VAL_32:.*]] = arith.muli %[[C1_I64]], %[[VAL_31]] : i64
375-
// CHECK: %[[FALSE:.*]] = arith.constant false
376-
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
377-
// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
378-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_33]], %[[VAL_34]], %[[VAL_32]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
372+
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
373+
// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
374+
// CHECK: "llvm.intr.memmove"(%[[VAL_33]], %[[VAL_34]], %[[VAL_32]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
379375
// CHECK: %[[C1:.*]] = arith.constant 1 : index
380376
// CHECK: %[[VAL_35:.*]] = arith.subi %[[VAL_19]], %[[C1]] : index
381377
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8
@@ -448,10 +444,9 @@ func.func @_QPmin3(%arg0: !fir.boxchar<1> {fir.bindc_name = "c1"}, %arg1: !fir.b
448444
// CHECK: %[[C1_I64:.*]] = arith.constant 1 : i64
449445
// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (index) -> i64
450446
// CHECK: %[[VAL_32:.*]] = arith.muli %[[C1_I64]], %[[VAL_31]] : i64
451-
// CHECK: %[[FALSE:.*]] = arith.constant false
452-
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
453-
// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
454-
// CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[VAL_33]], %[[VAL_34]], %[[VAL_32]], %[[FALSE]]) : (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
447+
// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_28]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
448+
// CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<!fir.char<1,?>>) -> !llvm.ptr
449+
// CHECK: "llvm.intr.memmove"(%[[VAL_33]], %[[VAL_34]], %[[VAL_32]]) <{isVolatile = false}> : (!llvm.ptr, !llvm.ptr, i64) -> ()
455450
// CHECK: %[[C1:.*]] = arith.constant 1 : index
456451
// CHECK: %[[VAL_35:.*]] = arith.subi %[[VAL_19]], %[[C1]] : index
457452
// CHECK: %[[C32_I8:.*]] = arith.constant 32 : i8

0 commit comments

Comments
 (0)