Skip to content

Commit c8cac15

Browse files
committed
PreISelIntrinsicLowering: Check RuntimeLibcalls instead of TLI for memory functions
We need a better mechanism for expressing which calls you are allowed to emit and which calls are recognized. This should be applied to the 17 branch.
1 parent f11f90d commit c8cac15

File tree

7 files changed

+71
-29
lines changed

7 files changed

+71
-29
lines changed

llvm/include/llvm/CodeGen/CodeGenPassBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
579579
if (TM.useEmulatedTLS())
580580
addPass(LowerEmuTLSPass());
581581

582-
addPass(PreISelIntrinsicLoweringPass());
582+
addPass(PreISelIntrinsicLoweringPass(TM));
583583

584584
derived().addIRPasses(addPass);
585585
derived().addCodeGenPrepare(addPass);

llvm/include/llvm/CodeGen/PreISelIntrinsicLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@
1818
namespace llvm {
1919

2020
class Module;
21+
class TargetMachine;
2122

2223
struct PreISelIntrinsicLoweringPass
2324
: PassInfoMixin<PreISelIntrinsicLoweringPass> {
25+
const TargetMachine &TM;
26+
27+
PreISelIntrinsicLoweringPass(const TargetMachine &TM) : TM(TM) {}
2428
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
2529
};
2630

llvm/lib/CodeGen/PreISelIntrinsicLowering.cpp

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
1515
#include "llvm/Analysis/ObjCARCInstKind.h"
1616
#include "llvm/Analysis/ObjCARCUtil.h"
17-
#include "llvm/Analysis/TargetLibraryInfo.h"
1817
#include "llvm/Analysis/TargetTransformInfo.h"
1918
#include "llvm/CodeGen/Passes.h"
19+
#include "llvm/CodeGen/TargetLowering.h"
20+
#include "llvm/CodeGen/TargetPassConfig.h"
2021
#include "llvm/IR/Function.h"
2122
#include "llvm/IR/IRBuilder.h"
2223
#include "llvm/IR/Instructions.h"
@@ -26,6 +27,7 @@
2627
#include "llvm/InitializePasses.h"
2728
#include "llvm/Pass.h"
2829
#include "llvm/Support/Casting.h"
30+
#include "llvm/Target/TargetMachine.h"
2931
#include "llvm/Transforms/Utils/LowerMemIntrinsics.h"
3032

3133
using namespace llvm;
@@ -41,19 +43,19 @@ static cl::opt<int64_t> MemIntrinsicExpandSizeThresholdOpt(
4143
namespace {
4244

4345
struct PreISelIntrinsicLowering {
46+
const TargetMachine &TM;
4447
const function_ref<TargetTransformInfo &(Function &)> LookupTTI;
45-
const function_ref<TargetLibraryInfo &(Function &)> LookupLibInfo;
4648

4749
/// If this is true, assume it's preferably to leave memory intrinsic calls
4850
/// for replacement with a library call later. Otherwise this depends on
49-
/// TargetLibraryInfo availability of the corresponding function.
51+
/// TargetLoweringInfo availability of the corresponding function.
5052
const bool UseMemIntrinsicLibFunc;
5153

5254
explicit PreISelIntrinsicLowering(
55+
const TargetMachine &TM_,
5356
function_ref<TargetTransformInfo &(Function &)> LookupTTI_,
54-
function_ref<TargetLibraryInfo &(Function &)> LookupLibInfo_,
5557
bool UseMemIntrinsicLibFunc_ = true)
56-
: LookupTTI(LookupTTI_), LookupLibInfo(LookupLibInfo_),
58+
: TM(TM_), LookupTTI(LookupTTI_),
5759
UseMemIntrinsicLibFunc(UseMemIntrinsicLibFunc_) {}
5860

5961
static bool shouldExpandMemIntrinsicWithSize(Value *Size,
@@ -195,9 +197,15 @@ bool PreISelIntrinsicLowering::shouldExpandMemIntrinsicWithSize(
195197
return SizeVal > Threshold || Threshold == 0;
196198
}
197199

200+
static bool canEmitLibcall(const TargetLowering &TLI, RTLIB::Libcall LC) {
201+
// TODO: Should this consider the address space of the memcpy?
202+
return TLI.getLibcallName(LC) != nullptr;
203+
}
204+
198205
// TODO: Handle atomic memcpy and memcpy.inline
199206
// TODO: Pass ScalarEvolution
200207
bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
208+
const TargetLowering *TLI = TM.getSubtargetImpl(F)->getTargetLowering();
201209
Intrinsic::ID ID = F.getIntrinsicID();
202210
bool Changed = false;
203211

@@ -210,10 +218,10 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
210218
Function *ParentFunc = Memcpy->getFunction();
211219
const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
212220
if (shouldExpandMemIntrinsicWithSize(Memcpy->getLength(), TTI)) {
213-
if (UseMemIntrinsicLibFunc &&
214-
LookupLibInfo(*ParentFunc).has(LibFunc_memcpy))
221+
if (UseMemIntrinsicLibFunc && canEmitLibcall(*TLI, RTLIB::MEMCPY))
215222
break;
216223

224+
// TODO: For optsize, emit the loop into a separate function
217225
expandMemCpyAsLoop(Memcpy, TTI);
218226
Changed = true;
219227
Memcpy->eraseFromParent();
@@ -226,8 +234,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
226234
Function *ParentFunc = Memmove->getFunction();
227235
const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
228236
if (shouldExpandMemIntrinsicWithSize(Memmove->getLength(), TTI)) {
229-
if (UseMemIntrinsicLibFunc &&
230-
LookupLibInfo(*ParentFunc).has(LibFunc_memmove))
237+
if (UseMemIntrinsicLibFunc && canEmitLibcall(*TLI, RTLIB::MEMMOVE))
231238
break;
232239

233240
if (expandMemMoveAsLoop(Memmove, TTI)) {
@@ -243,8 +250,7 @@ bool PreISelIntrinsicLowering::expandMemIntrinsicUses(Function &F) const {
243250
Function *ParentFunc = Memset->getFunction();
244251
const TargetTransformInfo &TTI = LookupTTI(*ParentFunc);
245252
if (shouldExpandMemIntrinsicWithSize(Memset->getLength(), TTI)) {
246-
if (UseMemIntrinsicLibFunc &&
247-
LookupLibInfo(*Memset->getFunction()).has(LibFunc_memset))
253+
if (UseMemIntrinsicLibFunc && canEmitLibcall(*TLI, RTLIB::MEMSET))
248254
break;
249255

250256
expandMemSetAsLoop(Memset);
@@ -365,20 +371,17 @@ class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
365371
PreISelIntrinsicLoweringLegacyPass() : ModulePass(ID) {}
366372

367373
void getAnalysisUsage(AnalysisUsage &AU) const override {
368-
AU.addRequired<TargetLibraryInfoWrapperPass>();
369374
AU.addRequired<TargetTransformInfoWrapperPass>();
375+
AU.addRequired<TargetPassConfig>();
370376
}
371377

372378
bool runOnModule(Module &M) override {
373379
auto LookupTTI = [this](Function &F) -> TargetTransformInfo & {
374380
return this->getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
375381
};
376382

377-
auto LookupTLI = [this](Function &F) -> TargetLibraryInfo & {
378-
return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
379-
};
380-
381-
PreISelIntrinsicLowering Lowering(LookupTTI, LookupTLI);
383+
const auto &TM = getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
384+
PreISelIntrinsicLowering Lowering(TM, LookupTTI);
382385
return Lowering.lowerIntrinsics(M);
383386
}
384387
};
@@ -387,27 +390,28 @@ class PreISelIntrinsicLoweringLegacyPass : public ModulePass {
387390

388391
char PreISelIntrinsicLoweringLegacyPass::ID;
389392

390-
INITIALIZE_PASS(PreISelIntrinsicLoweringLegacyPass,
391-
"pre-isel-intrinsic-lowering", "Pre-ISel Intrinsic Lowering",
392-
false, false)
393+
INITIALIZE_PASS_BEGIN(PreISelIntrinsicLoweringLegacyPass,
394+
"pre-isel-intrinsic-lowering",
395+
"Pre-ISel Intrinsic Lowering", false, false)
396+
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
397+
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
398+
INITIALIZE_PASS_END(PreISelIntrinsicLoweringLegacyPass,
399+
"pre-isel-intrinsic-lowering",
400+
"Pre-ISel Intrinsic Lowering", false, false)
393401

394402
ModulePass *llvm::createPreISelIntrinsicLoweringPass() {
395-
return new PreISelIntrinsicLoweringLegacyPass;
403+
return new PreISelIntrinsicLoweringLegacyPass();
396404
}
397405

398406
PreservedAnalyses PreISelIntrinsicLoweringPass::run(Module &M,
399407
ModuleAnalysisManager &AM) {
400408
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
401409

402-
auto LookupTLI = [&FAM](Function &F) -> TargetLibraryInfo & {
403-
return FAM.getResult<TargetLibraryAnalysis>(F);
404-
};
405-
406410
auto LookupTTI = [&FAM](Function &F) -> TargetTransformInfo & {
407411
return FAM.getResult<TargetIRAnalysis>(F);
408412
};
409413

410-
PreISelIntrinsicLowering Lowering(LookupTTI, LookupTLI);
414+
PreISelIntrinsicLowering Lowering(TM, LookupTTI);
411415
if (!Lowering.lowerIntrinsics(M))
412416
return PreservedAnalyses::all();
413417
else
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; RUN: llc -mtriple=thumbv7em-apple-unknown-macho < %s | FileCheck %s
3+
4+
target datalayout = "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
5+
6+
declare void @llvm.memcpy.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) #0
7+
declare void @llvm.memmove.p0.p0.i32(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i32, i1 immarg) #0
8+
declare void @llvm.memset.p0.i32(ptr noalias nocapture writeonly, i8, i32, i1 immarg) #0
9+
10+
; Check we don't expand memcpy to a loop when the caller
11+
; even if we have no-builtins attached.
12+
13+
; CHECK: bl _memcpy
14+
define arm_aapcs_vfpcc void @test_memcpy(ptr %p1, ptr %p2) #1 {
15+
call void @llvm.memcpy.p0.p0.i32(ptr %p1, ptr %p2, i32 128, i1 false)
16+
ret void
17+
}
18+
19+
; CHECK: bl _memmove
20+
define arm_aapcs_vfpcc void @test_memmove(ptr %p1, ptr %p2) #1 {
21+
call void @llvm.memmove.p0.p0.i32(ptr %p1, ptr %p2, i32 128, i1 false)
22+
ret void
23+
}
24+
25+
; CHECK: bl _memset
26+
define arm_aapcs_vfpcc void @test_memset(ptr %p1) #1 {
27+
call void @llvm.memset.p0.i32(ptr %p1, i8 0, i32 128, i1 false)
28+
ret void
29+
}
30+
31+
attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
32+
attributes #1 = { "no-builtins" }
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
if not "X86" in config.root.targets:
2+
config.unsupported = True

llvm/test/Transforms/PreISelIntrinsicLowering/load-relative.ll renamed to llvm/test/Transforms/PreISelIntrinsicLowering/X86/load-relative.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
1+
; RUN: opt -mtriple=x86_64-pc-linux-gnu -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
22

33
; CHECK: define ptr @foo32(ptr [[P:%.*]], i32 [[O:%.*]])
44
define ptr @foo32(ptr %p, i32 %o) {

llvm/test/Transforms/PreISelIntrinsicLowering/objc-arc.ll renamed to llvm/test/Transforms/PreISelIntrinsicLowering/X86/objc-arc.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
1+
; RUN: opt -mtriple=x86_64-pc-linux-gnu -pre-isel-intrinsic-lowering -S -o - %s | FileCheck %s
22

33
; Make sure calls to the objc intrinsics are translated to calls in to the
44
; runtime

0 commit comments

Comments
 (0)