forked from OSchip/llvm-project
Revert Attributor patch series
Broke check-clang, see https://reviews.llvm.org/D102307#2869065 Ran `git revert -n ebbe149a6f08535ede848a531a601ae6591cfbc5..269416d41908bb670f67af689155d5ab8eea689a`
This commit is contained in:
parent
f01d45c378
commit
d3e7491333
|
@ -553,6 +553,63 @@ static llvm::Value *getNVPTXLaneID(CodeGenFunction &CGF) {
|
||||||
"nvptx_lane_id");
|
"nvptx_lane_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the value of the thread_limit clause in the teams directive.
|
||||||
|
/// For the 'generic' execution mode, the runtime encodes thread_limit in
|
||||||
|
/// the launch parameters, always starting thread_limit+warpSize threads per
|
||||||
|
/// CTA. The threads in the last warp are reserved for master execution.
|
||||||
|
/// For the 'spmd' execution mode, all threads in a CTA are part of the team.
|
||||||
|
static llvm::Value *getThreadLimit(CodeGenFunction &CGF,
|
||||||
|
bool IsInSPMDExecutionMode = false) {
|
||||||
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
|
auto &RT = static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
||||||
|
llvm::Value *ThreadLimit = nullptr;
|
||||||
|
if (IsInSPMDExecutionMode)
|
||||||
|
ThreadLimit = RT.getGPUNumThreads(CGF);
|
||||||
|
else {
|
||||||
|
llvm::Value *GPUNumThreads = RT.getGPUNumThreads(CGF);
|
||||||
|
llvm::Value *GPUWarpSize = RT.getGPUWarpSize(CGF);
|
||||||
|
ThreadLimit = Bld.CreateNUWSub(GPUNumThreads, GPUWarpSize, "thread_limit");
|
||||||
|
}
|
||||||
|
assert(ThreadLimit != nullptr && "Expected non-null ThreadLimit");
|
||||||
|
return ThreadLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the thread id of the OMP master thread.
|
||||||
|
/// The master thread id is the first thread (lane) of the last warp in the
|
||||||
|
/// GPU block. Warp size is assumed to be some power of 2.
|
||||||
|
/// Thread id is 0 indexed.
|
||||||
|
/// E.g: If NumThreads is 33, master id is 32.
|
||||||
|
/// If NumThreads is 64, master id is 32.
|
||||||
|
/// If NumThreads is 1024, master id is 992.
|
||||||
|
static llvm::Value *getMasterThreadID(CodeGenFunction &CGF) {
|
||||||
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
|
auto &RT = static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
||||||
|
llvm::Value *NumThreads = RT.getGPUNumThreads(CGF);
|
||||||
|
// We assume that the warp size is a power of 2.
|
||||||
|
llvm::Value *Mask = Bld.CreateNUWSub(RT.getGPUWarpSize(CGF), Bld.getInt32(1));
|
||||||
|
|
||||||
|
llvm::Value *NumThreadsSubOne = Bld.CreateNUWSub(NumThreads, Bld.getInt32(1));
|
||||||
|
return Bld.CreateAnd(NumThreadsSubOne, Bld.CreateNot(Mask), "master_tid");
|
||||||
|
}
|
||||||
|
|
||||||
|
CGOpenMPRuntimeGPU::WorkerFunctionState::WorkerFunctionState(
|
||||||
|
CodeGenModule &CGM, SourceLocation Loc)
|
||||||
|
: WorkerFn(nullptr), CGFI(CGM.getTypes().arrangeNullaryFunction()),
|
||||||
|
Loc(Loc) {
|
||||||
|
createWorkerFunction(CGM);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGOpenMPRuntimeGPU::WorkerFunctionState::createWorkerFunction(
|
||||||
|
CodeGenModule &CGM) {
|
||||||
|
// Create an worker function with no arguments.
|
||||||
|
|
||||||
|
WorkerFn = llvm::Function::Create(
|
||||||
|
CGM.getTypes().GetFunctionType(CGFI), llvm::GlobalValue::InternalLinkage,
|
||||||
|
/*placeholder=*/"_worker", &CGM.getModule());
|
||||||
|
CGM.SetInternalFunctionAttributes(GlobalDecl(), WorkerFn, CGFI);
|
||||||
|
WorkerFn->setDoesNotRecurse();
|
||||||
|
}
|
||||||
|
|
||||||
CGOpenMPRuntimeGPU::ExecutionMode
|
CGOpenMPRuntimeGPU::ExecutionMode
|
||||||
CGOpenMPRuntimeGPU::getExecutionMode() const {
|
CGOpenMPRuntimeGPU::getExecutionMode() const {
|
||||||
return CurrentExecutionMode;
|
return CurrentExecutionMode;
|
||||||
|
@ -1016,19 +1073,23 @@ void CGOpenMPRuntimeGPU::emitNonSPMDKernel(const OMPExecutableDirective &D,
|
||||||
const RegionCodeGenTy &CodeGen) {
|
const RegionCodeGenTy &CodeGen) {
|
||||||
ExecutionRuntimeModesRAII ModeRAII(CurrentExecutionMode);
|
ExecutionRuntimeModesRAII ModeRAII(CurrentExecutionMode);
|
||||||
EntryFunctionState EST;
|
EntryFunctionState EST;
|
||||||
|
WorkerFunctionState WST(CGM, D.getBeginLoc());
|
||||||
|
Work.clear();
|
||||||
WrapperFunctionsMap.clear();
|
WrapperFunctionsMap.clear();
|
||||||
|
|
||||||
// Emit target region as a standalone region.
|
// Emit target region as a standalone region.
|
||||||
class NVPTXPrePostActionTy : public PrePostActionTy {
|
class NVPTXPrePostActionTy : public PrePostActionTy {
|
||||||
CGOpenMPRuntimeGPU::EntryFunctionState &EST;
|
CGOpenMPRuntimeGPU::EntryFunctionState &EST;
|
||||||
|
CGOpenMPRuntimeGPU::WorkerFunctionState &WST;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NVPTXPrePostActionTy(CGOpenMPRuntimeGPU::EntryFunctionState &EST)
|
NVPTXPrePostActionTy(CGOpenMPRuntimeGPU::EntryFunctionState &EST,
|
||||||
: EST(EST) {}
|
CGOpenMPRuntimeGPU::WorkerFunctionState &WST)
|
||||||
|
: EST(EST), WST(WST) {}
|
||||||
void Enter(CodeGenFunction &CGF) override {
|
void Enter(CodeGenFunction &CGF) override {
|
||||||
auto &RT =
|
auto &RT =
|
||||||
static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
||||||
RT.emitKernelInit(CGF, EST, /* IsSPMD */ false);
|
RT.emitNonSPMDEntryHeader(CGF, EST, WST);
|
||||||
// Skip target region initialization.
|
// Skip target region initialization.
|
||||||
RT.setLocThreadIdInsertPt(CGF, /*AtCurrentPoint=*/true);
|
RT.setLocThreadIdInsertPt(CGF, /*AtCurrentPoint=*/true);
|
||||||
}
|
}
|
||||||
|
@ -1036,33 +1097,93 @@ void CGOpenMPRuntimeGPU::emitNonSPMDKernel(const OMPExecutableDirective &D,
|
||||||
auto &RT =
|
auto &RT =
|
||||||
static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
||||||
RT.clearLocThreadIdInsertPt(CGF);
|
RT.clearLocThreadIdInsertPt(CGF);
|
||||||
RT.emitKernelDeinit(CGF, EST, /* IsSPMD */ false);
|
RT.emitNonSPMDEntryFooter(CGF, EST);
|
||||||
}
|
}
|
||||||
} Action(EST);
|
} Action(EST, WST);
|
||||||
CodeGen.setAction(Action);
|
CodeGen.setAction(Action);
|
||||||
IsInTTDRegion = true;
|
IsInTTDRegion = true;
|
||||||
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
|
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
|
||||||
IsOffloadEntry, CodeGen);
|
IsOffloadEntry, CodeGen);
|
||||||
IsInTTDRegion = false;
|
IsInTTDRegion = false;
|
||||||
|
|
||||||
|
// Now change the name of the worker function to correspond to this target
|
||||||
|
// region's entry function.
|
||||||
|
WST.WorkerFn->setName(Twine(OutlinedFn->getName(), "_worker"));
|
||||||
|
|
||||||
|
// Create the worker function
|
||||||
|
emitWorkerFunction(WST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntimeGPU::emitKernelInit(CodeGenFunction &CGF,
|
// Setup NVPTX threads for master-worker OpenMP scheme.
|
||||||
EntryFunctionState &EST, bool IsSPMD) {
|
void CGOpenMPRuntimeGPU::emitNonSPMDEntryHeader(CodeGenFunction &CGF,
|
||||||
|
EntryFunctionState &EST,
|
||||||
|
WorkerFunctionState &WST) {
|
||||||
CGBuilderTy &Bld = CGF.Builder;
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
Bld.restoreIP(OMPBuilder.createTargetInit(Bld, IsSPMD, requiresFullRuntime()));
|
|
||||||
IsInTargetMasterThreadRegion = IsSPMD;
|
llvm::BasicBlock *WorkerBB = CGF.createBasicBlock(".worker");
|
||||||
if (!IsSPMD)
|
llvm::BasicBlock *MasterCheckBB = CGF.createBasicBlock(".mastercheck");
|
||||||
emitGenericVarsProlog(CGF, EST.Loc);
|
llvm::BasicBlock *MasterBB = CGF.createBasicBlock(".master");
|
||||||
|
EST.ExitBB = CGF.createBasicBlock(".exit");
|
||||||
|
|
||||||
|
auto &RT = static_cast<CGOpenMPRuntimeGPU &>(CGF.CGM.getOpenMPRuntime());
|
||||||
|
llvm::Value *GPUThreadID = RT.getGPUThreadID(CGF);
|
||||||
|
llvm::Value *ThreadLimit = getThreadLimit(CGF);
|
||||||
|
llvm::Value *IsWorker = Bld.CreateICmpULT(GPUThreadID, ThreadLimit);
|
||||||
|
Bld.CreateCondBr(IsWorker, WorkerBB, MasterCheckBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(WorkerBB);
|
||||||
|
emitCall(CGF, WST.Loc, WST.WorkerFn);
|
||||||
|
CGF.EmitBranch(EST.ExitBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(MasterCheckBB);
|
||||||
|
GPUThreadID = RT.getGPUThreadID(CGF);
|
||||||
|
llvm::Value *MasterThreadID = getMasterThreadID(CGF);
|
||||||
|
llvm::Value *IsMaster = Bld.CreateICmpEQ(GPUThreadID, MasterThreadID);
|
||||||
|
Bld.CreateCondBr(IsMaster, MasterBB, EST.ExitBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(MasterBB);
|
||||||
|
IsInTargetMasterThreadRegion = true;
|
||||||
|
// SEQUENTIAL (MASTER) REGION START
|
||||||
|
// First action in sequential region:
|
||||||
|
// Initialize the state of the OpenMP runtime library on the GPU.
|
||||||
|
// TODO: Optimize runtime initialization and pass in correct value.
|
||||||
|
llvm::Value *Args[] = {getThreadLimit(CGF),
|
||||||
|
Bld.getInt16(/*RequiresOMPRuntime=*/1)};
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_kernel_init),
|
||||||
|
Args);
|
||||||
|
|
||||||
|
emitGenericVarsProlog(CGF, WST.Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntimeGPU::emitKernelDeinit(CodeGenFunction &CGF,
|
void CGOpenMPRuntimeGPU::emitNonSPMDEntryFooter(CodeGenFunction &CGF,
|
||||||
EntryFunctionState &EST,
|
EntryFunctionState &EST) {
|
||||||
bool IsSPMD) {
|
IsInTargetMasterThreadRegion = false;
|
||||||
if (!IsSPMD)
|
if (!CGF.HaveInsertPoint())
|
||||||
emitGenericVarsEpilog(CGF);
|
return;
|
||||||
|
|
||||||
CGBuilderTy &Bld = CGF.Builder;
|
emitGenericVarsEpilog(CGF);
|
||||||
OMPBuilder.createTargetDeinit(Bld, IsSPMD, requiresFullRuntime());
|
|
||||||
|
if (!EST.ExitBB)
|
||||||
|
EST.ExitBB = CGF.createBasicBlock(".exit");
|
||||||
|
|
||||||
|
llvm::BasicBlock *TerminateBB = CGF.createBasicBlock(".termination.notifier");
|
||||||
|
CGF.EmitBranch(TerminateBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(TerminateBB);
|
||||||
|
// Signal termination condition.
|
||||||
|
// TODO: Optimize runtime initialization and pass in correct value.
|
||||||
|
llvm::Value *Args[] = {CGF.Builder.getInt16(/*IsOMPRuntimeInitialized=*/1)};
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_kernel_deinit),
|
||||||
|
Args);
|
||||||
|
// Barrier to terminate worker threads.
|
||||||
|
syncCTAThreads(CGF);
|
||||||
|
// Master thread jumps to exit point.
|
||||||
|
CGF.EmitBranch(EST.ExitBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(EST.ExitBB);
|
||||||
|
EST.ExitBB = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntimeGPU::emitSPMDKernel(const OMPExecutableDirective &D,
|
void CGOpenMPRuntimeGPU::emitSPMDKernel(const OMPExecutableDirective &D,
|
||||||
|
@ -1081,21 +1202,23 @@ void CGOpenMPRuntimeGPU::emitSPMDKernel(const OMPExecutableDirective &D,
|
||||||
class NVPTXPrePostActionTy : public PrePostActionTy {
|
class NVPTXPrePostActionTy : public PrePostActionTy {
|
||||||
CGOpenMPRuntimeGPU &RT;
|
CGOpenMPRuntimeGPU &RT;
|
||||||
CGOpenMPRuntimeGPU::EntryFunctionState &EST;
|
CGOpenMPRuntimeGPU::EntryFunctionState &EST;
|
||||||
|
const OMPExecutableDirective &D;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NVPTXPrePostActionTy(CGOpenMPRuntimeGPU &RT,
|
NVPTXPrePostActionTy(CGOpenMPRuntimeGPU &RT,
|
||||||
CGOpenMPRuntimeGPU::EntryFunctionState &EST)
|
CGOpenMPRuntimeGPU::EntryFunctionState &EST,
|
||||||
: RT(RT), EST(EST) {}
|
const OMPExecutableDirective &D)
|
||||||
|
: RT(RT), EST(EST), D(D) {}
|
||||||
void Enter(CodeGenFunction &CGF) override {
|
void Enter(CodeGenFunction &CGF) override {
|
||||||
RT.emitKernelInit(CGF, EST, /* IsSPMD */ true);
|
RT.emitSPMDEntryHeader(CGF, EST, D);
|
||||||
// Skip target region initialization.
|
// Skip target region initialization.
|
||||||
RT.setLocThreadIdInsertPt(CGF, /*AtCurrentPoint=*/true);
|
RT.setLocThreadIdInsertPt(CGF, /*AtCurrentPoint=*/true);
|
||||||
}
|
}
|
||||||
void Exit(CodeGenFunction &CGF) override {
|
void Exit(CodeGenFunction &CGF) override {
|
||||||
RT.clearLocThreadIdInsertPt(CGF);
|
RT.clearLocThreadIdInsertPt(CGF);
|
||||||
RT.emitKernelDeinit(CGF, EST, /* IsSPMD */ true);
|
RT.emitSPMDEntryFooter(CGF, EST);
|
||||||
}
|
}
|
||||||
} Action(*this, EST);
|
} Action(*this, EST, D);
|
||||||
CodeGen.setAction(Action);
|
CodeGen.setAction(Action);
|
||||||
IsInTTDRegion = true;
|
IsInTTDRegion = true;
|
||||||
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
|
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
|
||||||
|
@ -1103,6 +1226,54 @@ void CGOpenMPRuntimeGPU::emitSPMDKernel(const OMPExecutableDirective &D,
|
||||||
IsInTTDRegion = false;
|
IsInTTDRegion = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGOpenMPRuntimeGPU::emitSPMDEntryHeader(
|
||||||
|
CodeGenFunction &CGF, EntryFunctionState &EST,
|
||||||
|
const OMPExecutableDirective &D) {
|
||||||
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
|
|
||||||
|
// Setup BBs in entry function.
|
||||||
|
llvm::BasicBlock *ExecuteBB = CGF.createBasicBlock(".execute");
|
||||||
|
EST.ExitBB = CGF.createBasicBlock(".exit");
|
||||||
|
|
||||||
|
llvm::Value *Args[] = {getThreadLimit(CGF, /*IsInSPMDExecutionMode=*/true),
|
||||||
|
/*RequiresOMPRuntime=*/
|
||||||
|
Bld.getInt16(RequiresFullRuntime ? 1 : 0)};
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_spmd_kernel_init),
|
||||||
|
Args);
|
||||||
|
|
||||||
|
CGF.EmitBranch(ExecuteBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(ExecuteBB);
|
||||||
|
|
||||||
|
IsInTargetMasterThreadRegion = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGOpenMPRuntimeGPU::emitSPMDEntryFooter(CodeGenFunction &CGF,
|
||||||
|
EntryFunctionState &EST) {
|
||||||
|
IsInTargetMasterThreadRegion = false;
|
||||||
|
if (!CGF.HaveInsertPoint())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!EST.ExitBB)
|
||||||
|
EST.ExitBB = CGF.createBasicBlock(".exit");
|
||||||
|
|
||||||
|
llvm::BasicBlock *OMPDeInitBB = CGF.createBasicBlock(".omp.deinit");
|
||||||
|
CGF.EmitBranch(OMPDeInitBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(OMPDeInitBB);
|
||||||
|
// DeInitialize the OMP state in the runtime; called by all active threads.
|
||||||
|
llvm::Value *Args[] = {/*RequiresOMPRuntime=*/
|
||||||
|
CGF.Builder.getInt16(RequiresFullRuntime ? 1 : 0)};
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_spmd_kernel_deinit_v2),
|
||||||
|
Args);
|
||||||
|
CGF.EmitBranch(EST.ExitBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(EST.ExitBB);
|
||||||
|
EST.ExitBB = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Create a unique global variable to indicate the execution mode of this target
|
// Create a unique global variable to indicate the execution mode of this target
|
||||||
// region. The execution mode is either 'generic', or 'spmd' depending on the
|
// region. The execution mode is either 'generic', or 'spmd' depending on the
|
||||||
// target directive. This variable is picked up by the offload library to setup
|
// target directive. This variable is picked up by the offload library to setup
|
||||||
|
@ -1119,6 +1290,137 @@ static void setPropertyExecutionMode(CodeGenModule &CGM, StringRef Name,
|
||||||
CGM.addCompilerUsedGlobal(GVMode);
|
CGM.addCompilerUsedGlobal(GVMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGOpenMPRuntimeGPU::emitWorkerFunction(WorkerFunctionState &WST) {
|
||||||
|
ASTContext &Ctx = CGM.getContext();
|
||||||
|
|
||||||
|
CodeGenFunction CGF(CGM, /*suppressNewContext=*/true);
|
||||||
|
CGF.StartFunction(GlobalDecl(), Ctx.VoidTy, WST.WorkerFn, WST.CGFI, {},
|
||||||
|
WST.Loc, WST.Loc);
|
||||||
|
emitWorkerLoop(CGF, WST);
|
||||||
|
CGF.FinishFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGOpenMPRuntimeGPU::emitWorkerLoop(CodeGenFunction &CGF,
|
||||||
|
WorkerFunctionState &WST) {
|
||||||
|
//
|
||||||
|
// The workers enter this loop and wait for parallel work from the master.
|
||||||
|
// When the master encounters a parallel region it sets up the work + variable
|
||||||
|
// arguments, and wakes up the workers. The workers first check to see if
|
||||||
|
// they are required for the parallel region, i.e., within the # of requested
|
||||||
|
// parallel threads. The activated workers load the variable arguments and
|
||||||
|
// execute the parallel work.
|
||||||
|
//
|
||||||
|
|
||||||
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
|
|
||||||
|
llvm::BasicBlock *AwaitBB = CGF.createBasicBlock(".await.work");
|
||||||
|
llvm::BasicBlock *SelectWorkersBB = CGF.createBasicBlock(".select.workers");
|
||||||
|
llvm::BasicBlock *ExecuteBB = CGF.createBasicBlock(".execute.parallel");
|
||||||
|
llvm::BasicBlock *TerminateBB = CGF.createBasicBlock(".terminate.parallel");
|
||||||
|
llvm::BasicBlock *BarrierBB = CGF.createBasicBlock(".barrier.parallel");
|
||||||
|
llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".exit");
|
||||||
|
|
||||||
|
CGF.EmitBranch(AwaitBB);
|
||||||
|
|
||||||
|
// Workers wait for work from master.
|
||||||
|
CGF.EmitBlock(AwaitBB);
|
||||||
|
// Wait for parallel work
|
||||||
|
syncCTAThreads(CGF);
|
||||||
|
|
||||||
|
Address WorkFn =
|
||||||
|
CGF.CreateDefaultAlignTempAlloca(CGF.Int8PtrTy, /*Name=*/"work_fn");
|
||||||
|
Address ExecStatus =
|
||||||
|
CGF.CreateDefaultAlignTempAlloca(CGF.Int8Ty, /*Name=*/"exec_status");
|
||||||
|
CGF.InitTempAlloca(ExecStatus, Bld.getInt8(/*C=*/0));
|
||||||
|
CGF.InitTempAlloca(WorkFn, llvm::Constant::getNullValue(CGF.Int8PtrTy));
|
||||||
|
|
||||||
|
// TODO: Optimize runtime initialization and pass in correct value.
|
||||||
|
llvm::Value *Args[] = {WorkFn.getPointer()};
|
||||||
|
llvm::Value *Ret =
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_kernel_parallel),
|
||||||
|
Args);
|
||||||
|
Bld.CreateStore(Bld.CreateZExt(Ret, CGF.Int8Ty), ExecStatus);
|
||||||
|
|
||||||
|
// On termination condition (workid == 0), exit loop.
|
||||||
|
llvm::Value *WorkID = Bld.CreateLoad(WorkFn);
|
||||||
|
llvm::Value *ShouldTerminate = Bld.CreateIsNull(WorkID, "should_terminate");
|
||||||
|
Bld.CreateCondBr(ShouldTerminate, ExitBB, SelectWorkersBB);
|
||||||
|
|
||||||
|
// Activate requested workers.
|
||||||
|
CGF.EmitBlock(SelectWorkersBB);
|
||||||
|
llvm::Value *IsActive =
|
||||||
|
Bld.CreateIsNotNull(Bld.CreateLoad(ExecStatus), "is_active");
|
||||||
|
Bld.CreateCondBr(IsActive, ExecuteBB, BarrierBB);
|
||||||
|
|
||||||
|
// Signal start of parallel region.
|
||||||
|
CGF.EmitBlock(ExecuteBB);
|
||||||
|
// Skip initialization.
|
||||||
|
setLocThreadIdInsertPt(CGF, /*AtCurrentPoint=*/true);
|
||||||
|
|
||||||
|
// Process work items: outlined parallel functions.
|
||||||
|
for (llvm::Function *W : Work) {
|
||||||
|
// Try to match this outlined function.
|
||||||
|
llvm::Value *ID = Bld.CreatePointerBitCastOrAddrSpaceCast(W, CGM.Int8PtrTy);
|
||||||
|
|
||||||
|
llvm::Value *WorkFnMatch =
|
||||||
|
Bld.CreateICmpEQ(Bld.CreateLoad(WorkFn), ID, "work_match");
|
||||||
|
|
||||||
|
llvm::BasicBlock *ExecuteFNBB = CGF.createBasicBlock(".execute.fn");
|
||||||
|
llvm::BasicBlock *CheckNextBB = CGF.createBasicBlock(".check.next");
|
||||||
|
Bld.CreateCondBr(WorkFnMatch, ExecuteFNBB, CheckNextBB);
|
||||||
|
|
||||||
|
// Execute this outlined function.
|
||||||
|
CGF.EmitBlock(ExecuteFNBB);
|
||||||
|
|
||||||
|
// Insert call to work function via shared wrapper. The shared
|
||||||
|
// wrapper takes two arguments:
|
||||||
|
// - the parallelism level;
|
||||||
|
// - the thread ID;
|
||||||
|
emitCall(CGF, WST.Loc, W,
|
||||||
|
{Bld.getInt16(/*ParallelLevel=*/0), getThreadID(CGF, WST.Loc)});
|
||||||
|
|
||||||
|
// Go to end of parallel region.
|
||||||
|
CGF.EmitBranch(TerminateBB);
|
||||||
|
|
||||||
|
CGF.EmitBlock(CheckNextBB);
|
||||||
|
}
|
||||||
|
// Default case: call to outlined function through pointer if the target
|
||||||
|
// region makes a declare target call that may contain an orphaned parallel
|
||||||
|
// directive.
|
||||||
|
auto *ParallelFnTy =
|
||||||
|
llvm::FunctionType::get(CGM.VoidTy, {CGM.Int16Ty, CGM.Int32Ty},
|
||||||
|
/*isVarArg=*/false);
|
||||||
|
llvm::Value *WorkFnCast =
|
||||||
|
Bld.CreateBitCast(WorkID, ParallelFnTy->getPointerTo());
|
||||||
|
// Insert call to work function via shared wrapper. The shared
|
||||||
|
// wrapper takes two arguments:
|
||||||
|
// - the parallelism level;
|
||||||
|
// - the thread ID;
|
||||||
|
emitCall(CGF, WST.Loc, {ParallelFnTy, WorkFnCast},
|
||||||
|
{Bld.getInt16(/*ParallelLevel=*/0), getThreadID(CGF, WST.Loc)});
|
||||||
|
// Go to end of parallel region.
|
||||||
|
CGF.EmitBranch(TerminateBB);
|
||||||
|
|
||||||
|
// Signal end of parallel region.
|
||||||
|
CGF.EmitBlock(TerminateBB);
|
||||||
|
CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
|
||||||
|
CGM.getModule(), OMPRTL___kmpc_kernel_end_parallel),
|
||||||
|
llvm::None);
|
||||||
|
CGF.EmitBranch(BarrierBB);
|
||||||
|
|
||||||
|
// All active and inactive workers wait at a barrier after parallel region.
|
||||||
|
CGF.EmitBlock(BarrierBB);
|
||||||
|
// Barrier after parallel region.
|
||||||
|
syncCTAThreads(CGF);
|
||||||
|
CGF.EmitBranch(AwaitBB);
|
||||||
|
|
||||||
|
// Exit target region.
|
||||||
|
CGF.EmitBlock(ExitBB);
|
||||||
|
// Skip initialization.
|
||||||
|
clearLocThreadIdInsertPt(CGF);
|
||||||
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntimeGPU::createOffloadEntry(llvm::Constant *ID,
|
void CGOpenMPRuntimeGPU::createOffloadEntry(llvm::Constant *ID,
|
||||||
llvm::Constant *Addr,
|
llvm::Constant *Addr,
|
||||||
uint64_t Size, int32_t,
|
uint64_t Size, int32_t,
|
||||||
|
@ -1504,8 +1806,11 @@ void CGOpenMPRuntimeGPU::emitParallelCall(CodeGenFunction &CGF,
|
||||||
CGBuilderTy &Bld = CGF.Builder;
|
CGBuilderTy &Bld = CGF.Builder;
|
||||||
llvm::Function *WFn = WrapperFunctionsMap[OutlinedFn];
|
llvm::Function *WFn = WrapperFunctionsMap[OutlinedFn];
|
||||||
llvm::Value *ID = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
|
llvm::Value *ID = llvm::ConstantPointerNull::get(CGM.Int8PtrTy);
|
||||||
if (WFn)
|
if (WFn) {
|
||||||
ID = Bld.CreateBitOrPointerCast(WFn, CGM.Int8PtrTy);
|
ID = Bld.CreateBitOrPointerCast(WFn, CGM.Int8PtrTy);
|
||||||
|
// Remember for post-processing in worker loop.
|
||||||
|
Work.emplace_back(WFn);
|
||||||
|
}
|
||||||
llvm::Value *FnPtr = Bld.CreateBitOrPointerCast(OutlinedFn, CGM.Int8PtrTy);
|
llvm::Value *FnPtr = Bld.CreateBitOrPointerCast(OutlinedFn, CGM.Int8PtrTy);
|
||||||
|
|
||||||
// Create a private scope that will globalize the arguments
|
// Create a private scope that will globalize the arguments
|
||||||
|
|
|
@ -38,7 +38,19 @@ private:
|
||||||
llvm::SmallVector<llvm::Function *, 16> Work;
|
llvm::SmallVector<llvm::Function *, 16> Work;
|
||||||
|
|
||||||
struct EntryFunctionState {
|
struct EntryFunctionState {
|
||||||
|
llvm::BasicBlock *ExitBB = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WorkerFunctionState {
|
||||||
|
public:
|
||||||
|
llvm::Function *WorkerFn;
|
||||||
|
const CGFunctionInfo &CGFI;
|
||||||
SourceLocation Loc;
|
SourceLocation Loc;
|
||||||
|
|
||||||
|
WorkerFunctionState(CodeGenModule &CGM, SourceLocation Loc);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void createWorkerFunction(CodeGenModule &CGM);
|
||||||
};
|
};
|
||||||
|
|
||||||
ExecutionMode getExecutionMode() const;
|
ExecutionMode getExecutionMode() const;
|
||||||
|
@ -48,13 +60,20 @@ private:
|
||||||
/// Get barrier to synchronize all threads in a block.
|
/// Get barrier to synchronize all threads in a block.
|
||||||
void syncCTAThreads(CodeGenFunction &CGF);
|
void syncCTAThreads(CodeGenFunction &CGF);
|
||||||
|
|
||||||
/// Helper for target directive initialization.
|
/// Emit the worker function for the current target region.
|
||||||
void emitKernelInit(CodeGenFunction &CGF, EntryFunctionState &EST,
|
void emitWorkerFunction(WorkerFunctionState &WST);
|
||||||
bool IsSPMD);
|
|
||||||
|
|
||||||
/// Helper for target directive finalization.
|
/// Helper for worker function. Emit body of worker loop.
|
||||||
void emitKernelDeinit(CodeGenFunction &CGF, EntryFunctionState &EST,
|
void emitWorkerLoop(CodeGenFunction &CGF, WorkerFunctionState &WST);
|
||||||
bool IsSPMD);
|
|
||||||
|
/// Helper for non-SPMD target entry function. Guide the master and
|
||||||
|
/// worker threads to their respective locations.
|
||||||
|
void emitNonSPMDEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
|
||||||
|
WorkerFunctionState &WST);
|
||||||
|
|
||||||
|
/// Signal termination of OMP execution for non-SPMD target entry
|
||||||
|
/// function.
|
||||||
|
void emitNonSPMDEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
|
||||||
|
|
||||||
/// Helper for generic variables globalization prolog.
|
/// Helper for generic variables globalization prolog.
|
||||||
void emitGenericVarsProlog(CodeGenFunction &CGF, SourceLocation Loc,
|
void emitGenericVarsProlog(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
|
@ -63,6 +82,13 @@ private:
|
||||||
/// Helper for generic variables globalization epilog.
|
/// Helper for generic variables globalization epilog.
|
||||||
void emitGenericVarsEpilog(CodeGenFunction &CGF, bool WithSPMDCheck = false);
|
void emitGenericVarsEpilog(CodeGenFunction &CGF, bool WithSPMDCheck = false);
|
||||||
|
|
||||||
|
/// Helper for SPMD mode target directive's entry function.
|
||||||
|
void emitSPMDEntryHeader(CodeGenFunction &CGF, EntryFunctionState &EST,
|
||||||
|
const OMPExecutableDirective &D);
|
||||||
|
|
||||||
|
/// Signal termination of SPMD mode execution.
|
||||||
|
void emitSPMDEntryFooter(CodeGenFunction &CGF, EntryFunctionState &EST);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Base class overrides.
|
// Base class overrides.
|
||||||
//
|
//
|
||||||
|
|
|
@ -111,10 +111,7 @@ inline std::string getAllAssumeClauseOptions() {
|
||||||
/// Todo: Update kmp.h to include this file, and remove the enums in kmp.h
|
/// Todo: Update kmp.h to include this file, and remove the enums in kmp.h
|
||||||
/// To complete this, more enum values will need to be moved here.
|
/// To complete this, more enum values will need to be moved here.
|
||||||
enum class OMPScheduleType {
|
enum class OMPScheduleType {
|
||||||
StaticChunked = 33,
|
|
||||||
Static = 34, // static unspecialized
|
Static = 34, // static unspecialized
|
||||||
DistributeChunked = 91,
|
|
||||||
Distribute = 92,
|
|
||||||
DynamicChunked = 35,
|
DynamicChunked = 35,
|
||||||
GuidedChunked = 36, // guided unspecialized
|
GuidedChunked = 36, // guided unspecialized
|
||||||
Runtime = 37,
|
Runtime = 37,
|
||||||
|
|
|
@ -779,29 +779,6 @@ public:
|
||||||
llvm::ConstantInt *Size,
|
llvm::ConstantInt *Size,
|
||||||
const llvm::Twine &Name = Twine(""));
|
const llvm::Twine &Name = Twine(""));
|
||||||
|
|
||||||
/// The `omp target` interface
|
|
||||||
///
|
|
||||||
/// For more information about the usage of this interface,
|
|
||||||
/// \see openmp/libomptarget/deviceRTLs/common/include/target.h
|
|
||||||
///
|
|
||||||
///{
|
|
||||||
|
|
||||||
/// Create a runtime call for kmpc_target_init
|
|
||||||
///
|
|
||||||
/// \param Loc The insert and source location description.
|
|
||||||
/// \param IsSPMD Flag to indicate if the kernel is an SPMD kernel or not.
|
|
||||||
/// \param RequiresFullRuntime Indicate if a full device runtime is necessary.
|
|
||||||
InsertPointTy createTargetInit(const LocationDescription &Loc, bool IsSPMD, bool RequiresFullRuntime);
|
|
||||||
|
|
||||||
/// Create a runtime call for kmpc_target_deinit
|
|
||||||
///
|
|
||||||
/// \param Loc The insert and source location description.
|
|
||||||
/// \param IsSPMD Flag to indicate if the kernel is an SPMD kernel or not.
|
|
||||||
/// \param RequiresFullRuntime Indicate if a full device runtime is necessary.
|
|
||||||
void createTargetDeinit(const LocationDescription &Loc, bool IsSPMD, bool RequiresFullRuntime);
|
|
||||||
|
|
||||||
///}
|
|
||||||
|
|
||||||
/// Declarations for LLVM-IR types (simple, array, function and structure) are
|
/// Declarations for LLVM-IR types (simple, array, function and structure) are
|
||||||
/// generated below. Their names are defined and used in OpenMPKinds.def. Here
|
/// generated below. Their names are defined and used in OpenMPKinds.def. Here
|
||||||
/// we provide the declarations, the initializeTypes function will provide the
|
/// we provide the declarations, the initializeTypes function will provide the
|
||||||
|
|
|
@ -409,8 +409,10 @@ __OMP_RTL(__kmpc_task_allow_completion_event, false, VoidPtr, IdentPtr,
|
||||||
/* Int */ Int32, /* kmp_task_t */ VoidPtr)
|
/* Int */ Int32, /* kmp_task_t */ VoidPtr)
|
||||||
|
|
||||||
/// OpenMP Device runtime functions
|
/// OpenMP Device runtime functions
|
||||||
__OMP_RTL(__kmpc_target_init, false, Int32, IdentPtr, Int1, Int1, Int1)
|
__OMP_RTL(__kmpc_kernel_init, false, Void, Int32, Int16)
|
||||||
__OMP_RTL(__kmpc_target_deinit, false, Void, IdentPtr, Int1, Int1)
|
__OMP_RTL(__kmpc_kernel_deinit, false, Void, Int16)
|
||||||
|
__OMP_RTL(__kmpc_spmd_kernel_init, false, Void, Int32, Int16)
|
||||||
|
__OMP_RTL(__kmpc_spmd_kernel_deinit_v2, false, Void, Int16)
|
||||||
__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
|
__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
|
||||||
__OMP_RTL(__kmpc_parallel_51, false, Void, IdentPtr, Int32, Int32, Int32, Int32,
|
__OMP_RTL(__kmpc_parallel_51, false, Void, IdentPtr, Int32, Int32, Int32, Int32,
|
||||||
VoidPtr, VoidPtr, VoidPtrPtr, SizeTy)
|
VoidPtr, VoidPtr, VoidPtrPtr, SizeTy)
|
||||||
|
|
|
@ -142,12 +142,6 @@ namespace AA {
|
||||||
/// instruction/argument of \p Scope.
|
/// instruction/argument of \p Scope.
|
||||||
bool isValidInScope(const Value &V, const Function *Scope);
|
bool isValidInScope(const Value &V, const Function *Scope);
|
||||||
|
|
||||||
/// Return true if \p V is a valid value at position \p CtxI, that is a
|
|
||||||
/// constant, an argument of the same function as \p CtxI, or an instruction in
|
|
||||||
/// that function that dominates \p CtxI.
|
|
||||||
bool isValidAtPosition(const Value &V, const Instruction &CtxI,
|
|
||||||
InformationCache &InfoCache);
|
|
||||||
|
|
||||||
/// Try to convert \p V to type \p Ty without introducing new instructions. If
|
/// Try to convert \p V to type \p Ty without introducing new instructions. If
|
||||||
/// this is not possible return `nullptr`. Note: this function basically knows
|
/// this is not possible return `nullptr`. Note: this function basically knows
|
||||||
/// how to cast various constants.
|
/// how to cast various constants.
|
||||||
|
@ -1120,7 +1114,7 @@ struct Attributor {
|
||||||
: Allocator(InfoCache.Allocator), Functions(Functions),
|
: Allocator(InfoCache.Allocator), Functions(Functions),
|
||||||
InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed),
|
InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed),
|
||||||
DeleteFns(DeleteFns), RewriteSignatures(RewriteSignatures),
|
DeleteFns(DeleteFns), RewriteSignatures(RewriteSignatures),
|
||||||
MaxFixpointIterations(None), OREGetter(None), PassName("") {}
|
MaxFixpointIterations(None), OREGetter(None), PassName("") {}
|
||||||
|
|
||||||
/// Constructor
|
/// Constructor
|
||||||
///
|
///
|
||||||
|
@ -1487,12 +1481,6 @@ struct Attributor {
|
||||||
bool &UsedAssumedInformation) {
|
bool &UsedAssumedInformation) {
|
||||||
return getAssumedSimplified(IRP, &AA, UsedAssumedInformation);
|
return getAssumedSimplified(IRP, &AA, UsedAssumedInformation);
|
||||||
}
|
}
|
||||||
Optional<Value *> getAssumedSimplified(const Value &V,
|
|
||||||
const AbstractAttribute &AA,
|
|
||||||
bool &UsedAssumedInformation) {
|
|
||||||
return getAssumedSimplified(IRPosition::value(V), AA,
|
|
||||||
UsedAssumedInformation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Register \p CB as a simplification callback.
|
/// Register \p CB as a simplification callback.
|
||||||
/// `Attributor::getAssumedSimplified` will use these callbacks before
|
/// `Attributor::getAssumedSimplified` will use these callbacks before
|
||||||
|
@ -1519,17 +1507,10 @@ private:
|
||||||
bool &UsedAssumedInformation);
|
bool &UsedAssumedInformation);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Translate \p V from the callee context into the call site context.
|
|
||||||
Optional<Value *>
|
|
||||||
translateArgumentToCallSiteContent(Optional<Value *> V, CallBase &CB,
|
|
||||||
const AbstractAttribute &AA,
|
|
||||||
bool &UsedAssumedInformation);
|
|
||||||
|
|
||||||
/// Return true if \p AA (or its context instruction) is assumed dead.
|
/// Return true if \p AA (or its context instruction) is assumed dead.
|
||||||
///
|
///
|
||||||
/// If \p LivenessAA is not provided it is queried.
|
/// If \p LivenessAA is not provided it is queried.
|
||||||
bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA,
|
bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA,
|
||||||
bool &UsedAssumedInformation,
|
|
||||||
bool CheckBBLivenessOnly = false,
|
bool CheckBBLivenessOnly = false,
|
||||||
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
||||||
|
|
||||||
|
@ -1537,7 +1518,7 @@ public:
|
||||||
///
|
///
|
||||||
/// If \p LivenessAA is not provided it is queried.
|
/// If \p LivenessAA is not provided it is queried.
|
||||||
bool isAssumedDead(const Instruction &I, const AbstractAttribute *QueryingAA,
|
bool isAssumedDead(const Instruction &I, const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *LivenessAA, bool &UsedAssumedInformation,
|
const AAIsDead *LivenessAA,
|
||||||
bool CheckBBLivenessOnly = false,
|
bool CheckBBLivenessOnly = false,
|
||||||
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
||||||
|
|
||||||
|
@ -1545,7 +1526,7 @@ public:
|
||||||
///
|
///
|
||||||
/// If \p FnLivenessAA is not provided it is queried.
|
/// If \p FnLivenessAA is not provided it is queried.
|
||||||
bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
|
bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool CheckBBLivenessOnly = false,
|
bool CheckBBLivenessOnly = false,
|
||||||
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
||||||
|
|
||||||
|
@ -1553,7 +1534,7 @@ public:
|
||||||
///
|
///
|
||||||
/// If \p FnLivenessAA is not provided it is queried.
|
/// If \p FnLivenessAA is not provided it is queried.
|
||||||
bool isAssumedDead(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
|
bool isAssumedDead(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool CheckBBLivenessOnly = false,
|
bool CheckBBLivenessOnly = false,
|
||||||
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
DepClassTy DepClass = DepClassTy::OPTIONAL);
|
||||||
|
|
||||||
|
@ -1736,23 +1717,17 @@ public:
|
||||||
bool checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
|
bool checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
|
||||||
const AbstractAttribute &QueryingAA,
|
const AbstractAttribute &QueryingAA,
|
||||||
const ArrayRef<unsigned> &Opcodes,
|
const ArrayRef<unsigned> &Opcodes,
|
||||||
bool &UsedAssumedInformation,
|
bool CheckBBLivenessOnly = false);
|
||||||
bool CheckBBLivenessOnly = false,
|
|
||||||
bool CheckPotentiallyDead = false);
|
|
||||||
|
|
||||||
/// Check \p Pred on all call-like instructions (=CallBased derived).
|
/// Check \p Pred on all call-like instructions (=CallBased derived).
|
||||||
///
|
///
|
||||||
/// See checkForAllCallLikeInstructions(...) for more information.
|
/// See checkForAllCallLikeInstructions(...) for more information.
|
||||||
bool checkForAllCallLikeInstructions(function_ref<bool(Instruction &)> Pred,
|
bool checkForAllCallLikeInstructions(function_ref<bool(Instruction &)> Pred,
|
||||||
const AbstractAttribute &QueryingAA,
|
const AbstractAttribute &QueryingAA) {
|
||||||
bool &UsedAssumedInformation,
|
return checkForAllInstructions(Pred, QueryingAA,
|
||||||
bool CheckBBLivenessOnly = false,
|
{(unsigned)Instruction::Invoke,
|
||||||
bool CheckPotentiallyDead = false) {
|
(unsigned)Instruction::CallBr,
|
||||||
return checkForAllInstructions(
|
(unsigned)Instruction::Call});
|
||||||
Pred, QueryingAA,
|
|
||||||
{(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
|
|
||||||
(unsigned)Instruction::Call},
|
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check \p Pred on all Read/Write instructions.
|
/// Check \p Pred on all Read/Write instructions.
|
||||||
|
@ -1761,8 +1736,7 @@ public:
|
||||||
/// to memory present in the information cache and return true if \p Pred
|
/// to memory present in the information cache and return true if \p Pred
|
||||||
/// holds on all of them.
|
/// holds on all of them.
|
||||||
bool checkForAllReadWriteInstructions(function_ref<bool(Instruction &)> Pred,
|
bool checkForAllReadWriteInstructions(function_ref<bool(Instruction &)> Pred,
|
||||||
AbstractAttribute &QueryingAA,
|
AbstractAttribute &QueryingAA);
|
||||||
bool &UsedAssumedInformation);
|
|
||||||
|
|
||||||
/// Create a shallow wrapper for \p F such that \p F has internal linkage
|
/// Create a shallow wrapper for \p F such that \p F has internal linkage
|
||||||
/// afterwards. It also sets the original \p F 's name to anonymous
|
/// afterwards. It also sets the original \p F 's name to anonymous
|
||||||
|
@ -2680,6 +2654,7 @@ struct AAReturnedValues
|
||||||
virtual llvm::iterator_range<const_iterator> returned_values() const = 0;
|
virtual llvm::iterator_range<const_iterator> returned_values() const = 0;
|
||||||
|
|
||||||
virtual size_t getNumReturnValues() const = 0;
|
virtual size_t getNumReturnValues() const = 0;
|
||||||
|
virtual const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const = 0;
|
||||||
|
|
||||||
/// Create an abstract attribute view for the position \p IRP.
|
/// Create an abstract attribute view for the position \p IRP.
|
||||||
static AAReturnedValues &createForPosition(const IRPosition &IRP,
|
static AAReturnedValues &createForPosition(const IRPosition &IRP,
|
||||||
|
@ -3507,6 +3482,9 @@ struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
|
||||||
/// Returns true if HeapToStack conversion is assumed to be possible.
|
/// Returns true if HeapToStack conversion is assumed to be possible.
|
||||||
virtual bool isAssumedHeapToStack(CallBase &CB) const = 0;
|
virtual bool isAssumedHeapToStack(CallBase &CB) const = 0;
|
||||||
|
|
||||||
|
/// Returns true if HeapToStack conversion is known to be possible.
|
||||||
|
virtual bool isKnownHeapToStack(CallBase &CB) const = 0;
|
||||||
|
|
||||||
/// Create an abstract attribute view for the position \p IRP.
|
/// Create an abstract attribute view for the position \p IRP.
|
||||||
static AAHeapToStack &createForPosition(const IRPosition &IRP, Attributor &A);
|
static AAHeapToStack &createForPosition(const IRPosition &IRP, Attributor &A);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "llvm/IR/DebugInfo.h"
|
#include "llvm/IR/DebugInfo.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
#include "llvm/IR/MDBuilder.h"
|
#include "llvm/IR/MDBuilder.h"
|
||||||
#include "llvm/IR/Value.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Error.h"
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||||
|
@ -2192,70 +2191,6 @@ CallInst *OpenMPIRBuilder::createCachedThreadPrivate(
|
||||||
return Builder.CreateCall(Fn, Args);
|
return Builder.CreateCall(Fn, Args);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenMPIRBuilder::InsertPointTy
|
|
||||||
OpenMPIRBuilder::createTargetInit(const LocationDescription &Loc, bool IsSPMD, bool RequiresFullRuntime) {
|
|
||||||
if (!updateToLocation(Loc))
|
|
||||||
return Loc.IP;
|
|
||||||
|
|
||||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
|
|
||||||
Value *Ident = getOrCreateIdent(SrcLocStr);
|
|
||||||
ConstantInt *IsSPMDVal = ConstantInt::getBool(Int32->getContext(), IsSPMD);
|
|
||||||
ConstantInt *UseGenericStateMachine =
|
|
||||||
ConstantInt::getBool(Int32->getContext(), !IsSPMD);
|
|
||||||
ConstantInt *RequiresFullRuntimeVal = ConstantInt::getBool(Int32->getContext(), RequiresFullRuntime);
|
|
||||||
|
|
||||||
Function *Fn = getOrCreateRuntimeFunctionPtr(
|
|
||||||
omp::RuntimeFunction::OMPRTL___kmpc_target_init);
|
|
||||||
|
|
||||||
CallInst *ThreadKind =
|
|
||||||
Builder.CreateCall(Fn, {Ident, IsSPMDVal, UseGenericStateMachine, RequiresFullRuntimeVal});
|
|
||||||
|
|
||||||
Value *ExecUserCode = Builder.CreateICmpEQ(
|
|
||||||
ThreadKind, ConstantInt::get(ThreadKind->getType(), -1), "exec_user_code");
|
|
||||||
|
|
||||||
// ThreadKind = __kmpc_target_init(...)
|
|
||||||
// if (ThreadKind == -1)
|
|
||||||
// user_code
|
|
||||||
// else
|
|
||||||
// return;
|
|
||||||
|
|
||||||
auto *UI = Builder.CreateUnreachable();
|
|
||||||
BasicBlock *CheckBB = UI->getParent();
|
|
||||||
BasicBlock *UserCodeEntryBB = CheckBB->splitBasicBlock(UI, "user_code.entry");
|
|
||||||
|
|
||||||
BasicBlock *WorkerExitBB = BasicBlock::Create(
|
|
||||||
CheckBB->getContext(), "worker.exit", CheckBB->getParent());
|
|
||||||
Builder.SetInsertPoint(WorkerExitBB);
|
|
||||||
Builder.CreateRetVoid();
|
|
||||||
|
|
||||||
auto *CheckBBTI = CheckBB->getTerminator();
|
|
||||||
Builder.SetInsertPoint(CheckBBTI);
|
|
||||||
Builder.CreateCondBr(ExecUserCode, UI->getParent(), WorkerExitBB);
|
|
||||||
|
|
||||||
CheckBBTI->eraseFromParent();
|
|
||||||
UI->eraseFromParent();
|
|
||||||
|
|
||||||
// Continue in the "user_code" block, see diagram above and in
|
|
||||||
// openmp/libomptarget/deviceRTLs/common/include/target.h .
|
|
||||||
return InsertPointTy(UserCodeEntryBB, UserCodeEntryBB->getFirstInsertionPt());
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenMPIRBuilder::createTargetDeinit(const LocationDescription &Loc,
|
|
||||||
bool IsSPMD, bool RequiresFullRuntime) {
|
|
||||||
if (!updateToLocation(Loc))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc);
|
|
||||||
Value *Ident = getOrCreateIdent(SrcLocStr);
|
|
||||||
ConstantInt *IsSPMDVal = ConstantInt::getBool(Int32->getContext(), IsSPMD);
|
|
||||||
ConstantInt *RequiresFullRuntimeVal = ConstantInt::getBool(Int32->getContext(), RequiresFullRuntime);
|
|
||||||
|
|
||||||
Function *Fn = getOrCreateRuntimeFunctionPtr(
|
|
||||||
omp::RuntimeFunction::OMPRTL___kmpc_target_deinit);
|
|
||||||
|
|
||||||
Builder.CreateCall(Fn, {Ident, IsSPMDVal, RequiresFullRuntimeVal});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
|
std::string OpenMPIRBuilder::getNameWithSeparators(ArrayRef<StringRef> Parts,
|
||||||
StringRef FirstSeparator,
|
StringRef FirstSeparator,
|
||||||
StringRef Separator) {
|
StringRef Separator) {
|
||||||
|
|
|
@ -33,5 +33,4 @@ StringSet<> llvm::KnownAssumptionStrings({
|
||||||
"omp_no_openmp", // OpenMP 5.1
|
"omp_no_openmp", // OpenMP 5.1
|
||||||
"omp_no_openmp_routines", // OpenMP 5.1
|
"omp_no_openmp_routines", // OpenMP 5.1
|
||||||
"omp_no_parallelism", // OpenMP 5.1
|
"omp_no_parallelism", // OpenMP 5.1
|
||||||
"ompx_spmd_amenable", // OpenMPOpt extension
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "llvm/Analysis/MustExecute.h"
|
#include "llvm/Analysis/MustExecute.h"
|
||||||
#include "llvm/Analysis/ValueTracking.h"
|
#include "llvm/Analysis/ValueTracking.h"
|
||||||
#include "llvm/IR/Attributes.h"
|
#include "llvm/IR/Attributes.h"
|
||||||
#include "llvm/IR/Constant.h"
|
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/GlobalValue.h"
|
#include "llvm/IR/GlobalValue.h"
|
||||||
#include "llvm/IR/IRBuilder.h"
|
#include "llvm/IR/IRBuilder.h"
|
||||||
|
@ -176,22 +175,6 @@ bool AA::isValidInScope(const Value &V, const Function *Scope) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AA::isValidAtPosition(const Value &V, const Instruction &CtxI,
|
|
||||||
InformationCache &InfoCache) {
|
|
||||||
if (isa<Constant>(V))
|
|
||||||
return true;
|
|
||||||
const Function *Scope = CtxI.getFunction();
|
|
||||||
if (auto *A = dyn_cast<Argument>(&V))
|
|
||||||
return A->getParent() == Scope;
|
|
||||||
if (auto *I = dyn_cast<Instruction>(&V))
|
|
||||||
if (I->getFunction() == Scope) {
|
|
||||||
const DominatorTree *DT =
|
|
||||||
InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Scope);
|
|
||||||
return DT && DT->dominates(I, &CtxI);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value *AA::getWithType(Value &V, Type &Ty) {
|
Value *AA::getWithType(Value &V, Type &Ty) {
|
||||||
if (V.getType() == &Ty)
|
if (V.getType() == &Ty)
|
||||||
return &V;
|
return &V;
|
||||||
|
@ -626,20 +609,8 @@ void IRPosition::verify() {
|
||||||
Optional<Constant *>
|
Optional<Constant *>
|
||||||
Attributor::getAssumedConstant(const Value &V, const AbstractAttribute &AA,
|
Attributor::getAssumedConstant(const Value &V, const AbstractAttribute &AA,
|
||||||
bool &UsedAssumedInformation) {
|
bool &UsedAssumedInformation) {
|
||||||
// First check all callbacks provided by outside AAs. If any of them returns
|
const auto &ValueSimplifyAA = getAAFor<AAValueSimplify>(
|
||||||
// a non-null value that is different from the associated value, or None, we
|
AA, IRPosition::value(V, AA.getCallBaseContext()), DepClassTy::NONE);
|
||||||
// assume it's simpliied.
|
|
||||||
IRPosition IRP = IRPosition::value(V, AA.getCallBaseContext());
|
|
||||||
for (auto &CB : SimplificationCallbacks[IRP]) {
|
|
||||||
Optional<Value *> SimplifiedV = CB(IRP, &AA, UsedAssumedInformation);
|
|
||||||
if (!SimplifiedV.hasValue())
|
|
||||||
return llvm::None;
|
|
||||||
if (*SimplifiedV && *SimplifiedV != &IRP.getAssociatedValue() &&
|
|
||||||
isa<Constant>(*SimplifiedV))
|
|
||||||
return cast<Constant>(*SimplifiedV);
|
|
||||||
}
|
|
||||||
const auto &ValueSimplifyAA =
|
|
||||||
getAAFor<AAValueSimplify>(AA, IRP, DepClassTy::NONE);
|
|
||||||
Optional<Value *> SimplifiedV =
|
Optional<Value *> SimplifiedV =
|
||||||
ValueSimplifyAA.getAssumedSimplifiedValue(*this);
|
ValueSimplifyAA.getAssumedSimplifiedValue(*this);
|
||||||
bool IsKnown = ValueSimplifyAA.isAtFixpoint();
|
bool IsKnown = ValueSimplifyAA.isAtFixpoint();
|
||||||
|
@ -699,21 +670,6 @@ Attributor::getAssumedSimplified(const IRPosition &IRP,
|
||||||
return const_cast<Value *>(&IRP.getAssociatedValue());
|
return const_cast<Value *>(&IRP.getAssociatedValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Value *> Attributor::translateArgumentToCallSiteContent(
|
|
||||||
Optional<Value *> V, CallBase &CB, const AbstractAttribute &AA,
|
|
||||||
bool &UsedAssumedInformation) {
|
|
||||||
if (!V.hasValue())
|
|
||||||
return V;
|
|
||||||
if (*V == nullptr || isa<Constant>(*V))
|
|
||||||
return V;
|
|
||||||
if (auto *Arg = dyn_cast<Argument>(*V))
|
|
||||||
if (!Arg->hasPointeeInMemoryValueAttr())
|
|
||||||
return getAssumedSimplified(
|
|
||||||
IRPosition::callsite_argument(CB, Arg->getArgNo()), AA,
|
|
||||||
UsedAssumedInformation);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Attributor::~Attributor() {
|
Attributor::~Attributor() {
|
||||||
// The abstract attributes are allocated via the BumpPtrAllocator Allocator,
|
// The abstract attributes are allocated via the BumpPtrAllocator Allocator,
|
||||||
// thus we cannot delete them. We can, and want to, destruct them though.
|
// thus we cannot delete them. We can, and want to, destruct them though.
|
||||||
|
@ -725,24 +681,21 @@ Attributor::~Attributor() {
|
||||||
|
|
||||||
bool Attributor::isAssumedDead(const AbstractAttribute &AA,
|
bool Attributor::isAssumedDead(const AbstractAttribute &AA,
|
||||||
const AAIsDead *FnLivenessAA,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool &UsedAssumedInformation,
|
|
||||||
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
||||||
const IRPosition &IRP = AA.getIRPosition();
|
const IRPosition &IRP = AA.getIRPosition();
|
||||||
if (!Functions.count(IRP.getAnchorScope()))
|
if (!Functions.count(IRP.getAnchorScope()))
|
||||||
return false;
|
return false;
|
||||||
return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
|
return isAssumedDead(IRP, &AA, FnLivenessAA, CheckBBLivenessOnly, DepClass);
|
||||||
CheckBBLivenessOnly, DepClass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Attributor::isAssumedDead(const Use &U,
|
bool Attributor::isAssumedDead(const Use &U,
|
||||||
const AbstractAttribute *QueryingAA,
|
const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *FnLivenessAA,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool &UsedAssumedInformation,
|
|
||||||
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
||||||
Instruction *UserI = dyn_cast<Instruction>(U.getUser());
|
Instruction *UserI = dyn_cast<Instruction>(U.getUser());
|
||||||
if (!UserI)
|
if (!UserI)
|
||||||
return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
|
return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
|
CheckBBLivenessOnly, DepClass);
|
||||||
|
|
||||||
if (auto *CB = dyn_cast<CallBase>(UserI)) {
|
if (auto *CB = dyn_cast<CallBase>(UserI)) {
|
||||||
// For call site argument uses we can check if the argument is
|
// For call site argument uses we can check if the argument is
|
||||||
|
@ -751,27 +704,25 @@ bool Attributor::isAssumedDead(const Use &U,
|
||||||
const IRPosition &CSArgPos =
|
const IRPosition &CSArgPos =
|
||||||
IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
|
IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
|
||||||
return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
|
return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly,
|
CheckBBLivenessOnly, DepClass);
|
||||||
DepClass);
|
|
||||||
}
|
}
|
||||||
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
|
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
|
||||||
const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
|
const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
|
||||||
return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
|
return isAssumedDead(RetPos, QueryingAA, FnLivenessAA, CheckBBLivenessOnly,
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
|
DepClass);
|
||||||
} else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
|
} else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
|
||||||
BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
|
BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
|
||||||
return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
|
return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
|
CheckBBLivenessOnly, DepClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isAssumedDead(IRPosition::value(*UserI), QueryingAA, FnLivenessAA,
|
return isAssumedDead(IRPosition::value(*UserI), QueryingAA, FnLivenessAA,
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
|
CheckBBLivenessOnly, DepClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Attributor::isAssumedDead(const Instruction &I,
|
bool Attributor::isAssumedDead(const Instruction &I,
|
||||||
const AbstractAttribute *QueryingAA,
|
const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *FnLivenessAA,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool &UsedAssumedInformation,
|
|
||||||
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
||||||
const IRPosition::CallBaseContext *CBCtx =
|
const IRPosition::CallBaseContext *CBCtx =
|
||||||
QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
|
QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
|
||||||
|
@ -787,8 +738,6 @@ bool Attributor::isAssumedDead(const Instruction &I,
|
||||||
FnLivenessAA->isAssumedDead(&I)) {
|
FnLivenessAA->isAssumedDead(&I)) {
|
||||||
if (QueryingAA)
|
if (QueryingAA)
|
||||||
recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
|
recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
|
||||||
if (!FnLivenessAA->isKnownDead(&I))
|
|
||||||
UsedAssumedInformation = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,8 +753,6 @@ bool Attributor::isAssumedDead(const Instruction &I,
|
||||||
if (IsDeadAA.isAssumedDead()) {
|
if (IsDeadAA.isAssumedDead()) {
|
||||||
if (QueryingAA)
|
if (QueryingAA)
|
||||||
recordDependence(IsDeadAA, *QueryingAA, DepClass);
|
recordDependence(IsDeadAA, *QueryingAA, DepClass);
|
||||||
if (!IsDeadAA.isKnownDead())
|
|
||||||
UsedAssumedInformation = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,11 +762,10 @@ bool Attributor::isAssumedDead(const Instruction &I,
|
||||||
bool Attributor::isAssumedDead(const IRPosition &IRP,
|
bool Attributor::isAssumedDead(const IRPosition &IRP,
|
||||||
const AbstractAttribute *QueryingAA,
|
const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *FnLivenessAA,
|
const AAIsDead *FnLivenessAA,
|
||||||
bool &UsedAssumedInformation,
|
|
||||||
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
bool CheckBBLivenessOnly, DepClassTy DepClass) {
|
||||||
Instruction *CtxI = IRP.getCtxI();
|
Instruction *CtxI = IRP.getCtxI();
|
||||||
if (CtxI &&
|
if (CtxI &&
|
||||||
isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
|
isAssumedDead(*CtxI, QueryingAA, FnLivenessAA,
|
||||||
/* CheckBBLivenessOnly */ true,
|
/* CheckBBLivenessOnly */ true,
|
||||||
CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
|
CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
|
||||||
return true;
|
return true;
|
||||||
|
@ -842,8 +788,6 @@ bool Attributor::isAssumedDead(const IRPosition &IRP,
|
||||||
if (IsDeadAA->isAssumedDead()) {
|
if (IsDeadAA->isAssumedDead()) {
|
||||||
if (QueryingAA)
|
if (QueryingAA)
|
||||||
recordDependence(*IsDeadAA, *QueryingAA, DepClass);
|
recordDependence(*IsDeadAA, *QueryingAA, DepClass);
|
||||||
if (!IsDeadAA->isKnownDead())
|
|
||||||
UsedAssumedInformation = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,6 +802,19 @@ bool Attributor::checkForAllUses(function_ref<bool(const Use &, bool &)> Pred,
|
||||||
if (V.use_empty())
|
if (V.use_empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// If the value is replaced by another one, for now a constant, we do not have
|
||||||
|
// uses. Note that this requires users of `checkForAllUses` to not recurse but
|
||||||
|
// instead use the `follow` callback argument to look at transitive users,
|
||||||
|
// however, that should be clear from the presence of the argument.
|
||||||
|
bool UsedAssumedInformation = false;
|
||||||
|
Optional<Constant *> C =
|
||||||
|
getAssumedConstant(V, QueryingAA, UsedAssumedInformation);
|
||||||
|
if (C.hasValue() && C.getValue()) {
|
||||||
|
LLVM_DEBUG(dbgs() << "[Attributor] Value is simplified, uses skipped: " << V
|
||||||
|
<< " -> " << *C.getValue() << "\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const IRPosition &IRP = QueryingAA.getIRPosition();
|
const IRPosition &IRP = QueryingAA.getIRPosition();
|
||||||
SmallVector<const Use *, 16> Worklist;
|
SmallVector<const Use *, 16> Worklist;
|
||||||
SmallPtrSet<const Use *, 16> Visited;
|
SmallPtrSet<const Use *, 16> Visited;
|
||||||
|
@ -880,8 +837,7 @@ bool Attributor::checkForAllUses(function_ref<bool(const Use &, bool &)> Pred,
|
||||||
continue;
|
continue;
|
||||||
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " in "
|
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " in "
|
||||||
<< *U->getUser() << "\n");
|
<< *U->getUser() << "\n");
|
||||||
bool UsedAssumedInformation = false;
|
if (isAssumedDead(*U, &QueryingAA, LivenessAA,
|
||||||
if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
|
|
||||||
/* CheckBBLivenessOnly */ false, LivenessDepClass)) {
|
/* CheckBBLivenessOnly */ false, LivenessDepClass)) {
|
||||||
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
|
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
|
||||||
continue;
|
continue;
|
||||||
|
@ -945,9 +901,7 @@ bool Attributor::checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,
|
||||||
const Use &U = *Uses[u];
|
const Use &U = *Uses[u];
|
||||||
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << *U << " in "
|
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << *U << " in "
|
||||||
<< *U.getUser() << "\n");
|
<< *U.getUser() << "\n");
|
||||||
bool UsedAssumedInformation = false;
|
if (isAssumedDead(U, QueryingAA, nullptr, /* CheckBBLivenessOnly */ true)) {
|
||||||
if (isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
|
|
||||||
/* CheckBBLivenessOnly */ true)) {
|
|
||||||
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
|
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1066,8 +1020,7 @@ static bool checkForAllInstructionsImpl(
|
||||||
Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
|
Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
|
||||||
function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
|
function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
|
||||||
const AAIsDead *LivenessAA, const ArrayRef<unsigned> &Opcodes,
|
const AAIsDead *LivenessAA, const ArrayRef<unsigned> &Opcodes,
|
||||||
bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
|
bool CheckBBLivenessOnly = false) {
|
||||||
bool CheckPotentiallyDead = false) {
|
|
||||||
for (unsigned Opcode : Opcodes) {
|
for (unsigned Opcode : Opcodes) {
|
||||||
// Check if we have instructions with this opcode at all first.
|
// Check if we have instructions with this opcode at all first.
|
||||||
auto *Insts = OpcodeInstMap.lookup(Opcode);
|
auto *Insts = OpcodeInstMap.lookup(Opcode);
|
||||||
|
@ -1076,9 +1029,8 @@ static bool checkForAllInstructionsImpl(
|
||||||
|
|
||||||
for (Instruction *I : *Insts) {
|
for (Instruction *I : *Insts) {
|
||||||
// Skip dead instructions.
|
// Skip dead instructions.
|
||||||
if (A && !CheckPotentiallyDead &&
|
if (A && A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
|
||||||
A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
|
CheckBBLivenessOnly))
|
||||||
UsedAssumedInformation, CheckBBLivenessOnly))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!Pred(*I))
|
if (!Pred(*I))
|
||||||
|
@ -1091,9 +1043,7 @@ static bool checkForAllInstructionsImpl(
|
||||||
bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
|
bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
|
||||||
const AbstractAttribute &QueryingAA,
|
const AbstractAttribute &QueryingAA,
|
||||||
const ArrayRef<unsigned> &Opcodes,
|
const ArrayRef<unsigned> &Opcodes,
|
||||||
bool &UsedAssumedInformation,
|
bool CheckBBLivenessOnly) {
|
||||||
bool CheckBBLivenessOnly,
|
|
||||||
bool CheckPotentiallyDead) {
|
|
||||||
|
|
||||||
const IRPosition &IRP = QueryingAA.getIRPosition();
|
const IRPosition &IRP = QueryingAA.getIRPosition();
|
||||||
// Since we need to provide instructions we have to have an exact definition.
|
// Since we need to provide instructions we have to have an exact definition.
|
||||||
|
@ -1104,23 +1054,21 @@ bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
|
||||||
// TODO: use the function scope once we have call site AAReturnedValues.
|
// TODO: use the function scope once we have call site AAReturnedValues.
|
||||||
const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
|
const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
|
||||||
const auto *LivenessAA =
|
const auto *LivenessAA =
|
||||||
(CheckBBLivenessOnly || CheckPotentiallyDead)
|
CheckBBLivenessOnly
|
||||||
? nullptr
|
? nullptr
|
||||||
: &(getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE));
|
: &(getAAFor<AAIsDead>(QueryingAA, QueryIRP, DepClassTy::NONE));
|
||||||
|
|
||||||
auto &OpcodeInstMap =
|
auto &OpcodeInstMap =
|
||||||
InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
|
InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
|
||||||
if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
|
if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
|
||||||
LivenessAA, Opcodes, UsedAssumedInformation,
|
LivenessAA, Opcodes, CheckBBLivenessOnly))
|
||||||
CheckBBLivenessOnly, CheckPotentiallyDead))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Attributor::checkForAllReadWriteInstructions(
|
bool Attributor::checkForAllReadWriteInstructions(
|
||||||
function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
|
function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA) {
|
||||||
bool &UsedAssumedInformation) {
|
|
||||||
|
|
||||||
const Function *AssociatedFunction =
|
const Function *AssociatedFunction =
|
||||||
QueryingAA.getIRPosition().getAssociatedFunction();
|
QueryingAA.getIRPosition().getAssociatedFunction();
|
||||||
|
@ -1135,8 +1083,7 @@ bool Attributor::checkForAllReadWriteInstructions(
|
||||||
for (Instruction *I :
|
for (Instruction *I :
|
||||||
InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
|
InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
|
||||||
// Skip dead instructions.
|
// Skip dead instructions.
|
||||||
if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA,
|
if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA))
|
||||||
UsedAssumedInformation))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!Pred(*I))
|
if (!Pred(*I))
|
||||||
|
@ -1162,6 +1109,7 @@ void Attributor::runTillFixpoint() {
|
||||||
else
|
else
|
||||||
MaxFixedPointIterations = SetFixpointIterations;
|
MaxFixedPointIterations = SetFixpointIterations;
|
||||||
|
|
||||||
|
|
||||||
SmallVector<AbstractAttribute *, 32> ChangedAAs;
|
SmallVector<AbstractAttribute *, 32> ChangedAAs;
|
||||||
SetVector<AbstractAttribute *> Worklist, InvalidAAs;
|
SetVector<AbstractAttribute *> Worklist, InvalidAAs;
|
||||||
Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
|
Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
|
||||||
|
@ -1314,9 +1262,7 @@ ChangeStatus Attributor::manifestAttributes() {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Skip dead code.
|
// Skip dead code.
|
||||||
bool UsedAssumedInformation = false;
|
if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true))
|
||||||
if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
|
|
||||||
/* CheckBBLivenessOnly */ true))
|
|
||||||
continue;
|
continue;
|
||||||
// Check if the manifest debug counter that allows skipping manifestation of
|
// Check if the manifest debug counter that allows skipping manifestation of
|
||||||
// AAs
|
// AAs
|
||||||
|
@ -1432,17 +1378,11 @@ ChangeStatus Attributor::cleanupIR() {
|
||||||
|
|
||||||
// Do not replace uses in returns if the value is a must-tail call we will
|
// Do not replace uses in returns if the value is a must-tail call we will
|
||||||
// not delete.
|
// not delete.
|
||||||
if (auto *RI = dyn_cast<ReturnInst>(U->getUser())) {
|
if (isa<ReturnInst>(U->getUser()))
|
||||||
if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
|
if (auto *CI = dyn_cast<CallInst>(OldV->stripPointerCasts()))
|
||||||
if (CI->isMustTailCall() &&
|
if (CI->isMustTailCall() &&
|
||||||
(!ToBeDeletedInsts.count(CI) || !isRunOn(*CI->getCaller())))
|
(!ToBeDeletedInsts.count(CI) || !isRunOn(*CI->getCaller())))
|
||||||
return;
|
return;
|
||||||
// If we rewrite a return and the new value is not an argument, strip the
|
|
||||||
// `returned` attribute as it is wrong now.
|
|
||||||
if (!isa<Argument>(NewV))
|
|
||||||
for (auto &Arg : RI->getFunction()->args())
|
|
||||||
Arg.removeAttr(Attribute::Returned);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not perform call graph altering changes outside the SCC.
|
// Do not perform call graph altering changes outside the SCC.
|
||||||
if (auto *CB = dyn_cast<CallBase>(U->getUser()))
|
if (auto *CB = dyn_cast<CallBase>(U->getUser()))
|
||||||
|
@ -1680,9 +1620,7 @@ ChangeStatus Attributor::updateAA(AbstractAttribute &AA) {
|
||||||
|
|
||||||
auto &AAState = AA.getState();
|
auto &AAState = AA.getState();
|
||||||
ChangeStatus CS = ChangeStatus::UNCHANGED;
|
ChangeStatus CS = ChangeStatus::UNCHANGED;
|
||||||
bool UsedAssumedInformation = false;
|
if (!isAssumedDead(AA, nullptr, /* CheckBBLivenessOnly */ true))
|
||||||
if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
|
|
||||||
/* CheckBBLivenessOnly */ true))
|
|
||||||
CS = AA.update(*this);
|
CS = AA.update(*this);
|
||||||
|
|
||||||
if (DV.empty()) {
|
if (DV.empty()) {
|
||||||
|
@ -1847,11 +1785,9 @@ bool Attributor::isValidFunctionSignatureRewrite(
|
||||||
|
|
||||||
// Forbid must-tail calls for now.
|
// Forbid must-tail calls for now.
|
||||||
// TODO:
|
// TODO:
|
||||||
bool UsedAssumedInformation = false;
|
|
||||||
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
|
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
|
||||||
if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
|
if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
|
||||||
nullptr, {Instruction::Call},
|
nullptr, {Instruction::Call})) {
|
||||||
UsedAssumedInformation)) {
|
|
||||||
LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
|
LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2369,7 +2305,10 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
||||||
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
|
if (!Callee->getReturnType()->isVoidTy() && !CB.use_empty()) {
|
||||||
|
|
||||||
IRPosition CBRetPos = IRPosition::callsite_returned(CB);
|
IRPosition CBRetPos = IRPosition::callsite_returned(CB);
|
||||||
getOrCreateAAFor<AAValueSimplify>(CBRetPos);
|
|
||||||
|
// Call site return integer values might be limited by a constant range.
|
||||||
|
if (Callee->getReturnType()->isIntegerTy())
|
||||||
|
getOrCreateAAFor<AAValueConstantRange>(CBRetPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int I = 0, E = CB.getNumArgOperands(); I < E; ++I) {
|
for (int I = 0, E = CB.getNumArgOperands(); I < E; ++I) {
|
||||||
|
@ -2418,12 +2357,10 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
||||||
|
|
||||||
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
|
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
|
||||||
bool Success;
|
bool Success;
|
||||||
bool UsedAssumedInformation = false;
|
|
||||||
Success = checkForAllInstructionsImpl(
|
Success = checkForAllInstructionsImpl(
|
||||||
nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
|
nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
|
||||||
{(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
|
{(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
|
||||||
(unsigned)Instruction::Call},
|
(unsigned)Instruction::Call});
|
||||||
UsedAssumedInformation);
|
|
||||||
(void)Success;
|
(void)Success;
|
||||||
assert(Success && "Expected the check call to be successful!");
|
assert(Success && "Expected the check call to be successful!");
|
||||||
|
|
||||||
|
@ -2438,8 +2375,7 @@ void Attributor::identifyDefaultAbstractAttributes(Function &F) {
|
||||||
};
|
};
|
||||||
Success = checkForAllInstructionsImpl(
|
Success = checkForAllInstructionsImpl(
|
||||||
nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
|
nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
|
||||||
{(unsigned)Instruction::Load, (unsigned)Instruction::Store},
|
{(unsigned)Instruction::Load, (unsigned)Instruction::Store});
|
||||||
UsedAssumedInformation);
|
|
||||||
(void)Success;
|
(void)Success;
|
||||||
assert(Success && "Expected the check call to be successful!");
|
assert(Success && "Expected the check call to be successful!");
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X, i32
|
||||||
;
|
;
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
|
||||||
; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval([[STRUCT_SS:%.*]]) align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree noundef nonnull byval(i32) align 4 dereferenceable(4) [[X:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree noundef nonnull byval([[STRUCT_SS:%.*]]) align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree noundef nonnull byval(i32) align 4 dereferenceable(4) [[X:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
|
; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B]], i32 0, i32 0
|
||||||
; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
|
; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
|
||||||
|
@ -24,7 +24,7 @@ define internal i32 @f(%struct.ss* byval(%struct.ss) %b, i32* byval(i32) %X, i32
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
|
||||||
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 noundef [[I:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: entry:
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4
|
; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]], align 4
|
; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]], align 4
|
||||||
|
@ -100,7 +100,7 @@ define i32 @test(i32* %X) {
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
|
; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
|
||||||
; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||||
; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
|
; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval(i32) align 4 [[X]]) #[[ATTR0]]
|
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_SS]]) align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval(i32) align 4 [[X]], i32 noundef zeroext 0) #[[ATTR0]]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
|
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
@ -117,7 +117,7 @@ define i32 @test(i32* %X) {
|
||||||
; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
|
||||||
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8
|
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 8
|
||||||
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
|
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]]) #[[ATTR0]]
|
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]], i32 noundef zeroext 0) #[[ATTR0]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
|
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
|
||||||
define internal i32 @callee(i1 %C, i32* %P) {
|
define internal i32 @callee(i1 %C, i32* %P) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
|
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee
|
||||||
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: (i1 noundef [[C:%.*]], i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[F:%.*]]
|
; IS__TUNIT_OPM-NEXT: br label [[F:%.*]]
|
||||||
; IS__TUNIT_OPM: T:
|
; IS__TUNIT_OPM: T:
|
||||||
; IS__TUNIT_OPM-NEXT: unreachable
|
; IS__TUNIT_OPM-NEXT: unreachable
|
||||||
|
@ -19,7 +19,7 @@ define internal i32 @callee(i1 %C, i32* %P) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
|
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee
|
||||||
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_NPM-SAME: (i1 noundef [[C:%.*]], i32 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4
|
; IS__TUNIT_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]], align 4
|
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[F:%.*]]
|
; IS__TUNIT_NPM-NEXT: br label [[F:%.*]]
|
||||||
|
@ -67,7 +67,7 @@ define i32 @foo() {
|
||||||
; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
|
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 17, i32* [[A]], align 4
|
; IS__TUNIT_OPM-NEXT: store i32 17, i32* [[A]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]]
|
; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @callee(i1 noundef false, i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
|
; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
@ -76,7 +76,7 @@ define i32 @foo() {
|
||||||
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 4
|
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 17, i32* [[A]], align 4
|
; IS__TUNIT_NPM-NEXT: store i32 17, i32* [[A]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 4
|
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i32 [[TMP1]]) #[[ATTR2:[0-9]+]]
|
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 noundef false, i32 [[TMP1]]) #[[ATTR2:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
|
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
|
|
@ -21,18 +21,31 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
; CHECK: @[[A:[a-zA-Z0-9_$"\\.-]+]] = internal global [[STRUCT_FOO:%.*]] { i32 1, i64 2 }, align 8
|
; CHECK: @[[A:[a-zA-Z0-9_$"\\.-]+]] = internal global [[STRUCT_FOO:%.*]] { i32 1, i64 2 }, align 8
|
||||||
;.
|
;.
|
||||||
define void @run() {
|
define void @run() {
|
||||||
|
; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
|
; IS________OPM-LABEL: define {{[^@]+}}@run
|
||||||
|
; IS________OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
|
; IS________OPM-NEXT: entry:
|
||||||
|
; IS________OPM-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct(%struct.Foo* nocapture nofree noundef nonnull readonly byval([[STRUCT_FOO:%.*]]) align 8 dereferenceable(16) @a) #[[ATTR0]]
|
||||||
|
; IS________OPM-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@run
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@run
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: entry:
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
; NOT_CGSCC_NPM-NEXT: [[TMP0:%.*]] = call i64 @CaptureAStruct() #[[ATTR0]]
|
; IS__TUNIT_NPM-NEXT: [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
|
||||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = call i64 @CaptureAStruct(i32 [[TMP0]], i64 [[TMP1]]) #[[ATTR0]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@run
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@run
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* getelementptr inbounds ([[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 0), align 8
|
||||||
|
; IS__CGSCC____-NEXT: [[A_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* @a, i32 0, i32 1
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -92,28 +105,53 @@ define internal i64 @CaptureAStruct(%struct.Foo* byval(%struct.Foo) %a) {
|
||||||
; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
|
; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
|
; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
|
||||||
;
|
;
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
|
; IS________OPM-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR0]] {
|
; IS________OPM-SAME: (%struct.Foo* noalias nofree noundef nonnull byval([[STRUCT_FOO:%.*]]) align 8 dereferenceable(16) [[A:%.*]]) #[[ATTR0]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: entry:
|
; IS________OPM-NEXT: entry:
|
||||||
; NOT_CGSCC_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
; IS________OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
||||||
; NOT_CGSCC_NPM-NEXT: br label [[LOOP:%.*]]
|
; IS________OPM-NEXT: br label [[LOOP:%.*]]
|
||||||
; NOT_CGSCC_NPM: loop:
|
; IS________OPM: loop:
|
||||||
; NOT_CGSCC_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ @a, [[LOOP]] ]
|
; IS________OPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||||
; NOT_CGSCC_NPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ @a, [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
|
; IS________OPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]], [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
|
||||||
; NOT_CGSCC_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
; IS________OPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
||||||
; NOT_CGSCC_NPM-NEXT: br label [[LOOP]]
|
; IS________OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A]], i64 0
|
||||||
|
; IS________OPM-NEXT: br label [[LOOP]]
|
||||||
|
;
|
||||||
|
; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||||
|
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32*
|
||||||
|
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 4
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]]
|
||||||
|
; IS__TUNIT_NPM: loop:
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]], [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
|
||||||
|
; IS__TUNIT_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i64 0
|
||||||
|
; IS__TUNIT_NPM-NEXT: br label [[LOOP]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
|
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR2:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
|
; IS__CGSCC____-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]], align 8
|
||||||
|
; IS__CGSCC____-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo* [[A_PRIV]] to i32*
|
||||||
|
; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 8
|
||||||
|
; IS__CGSCC____-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
|
||||||
|
; IS__CGSCC____-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8
|
||||||
; IS__CGSCC____-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
; IS__CGSCC____-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
|
||||||
; IS__CGSCC____-NEXT: br label [[LOOP:%.*]]
|
; IS__CGSCC____-NEXT: br label [[LOOP:%.*]]
|
||||||
; IS__CGSCC____: loop:
|
; IS__CGSCC____: loop:
|
||||||
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ @a, [[LOOP]] ]
|
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null, [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
|
||||||
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ @a, [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]], [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
|
||||||
; IS__CGSCC____-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
; IS__CGSCC____-NEXT: store %struct.Foo* [[PHI]], %struct.Foo** [[A_PTR]], align 8
|
||||||
|
; IS__CGSCC____-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i64 0
|
||||||
; IS__CGSCC____-NEXT: br label [[LOOP]]
|
; IS__CGSCC____-NEXT: br label [[LOOP]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -128,9 +166,9 @@ loop:
|
||||||
br label %loop
|
br label %loop
|
||||||
}
|
}
|
||||||
;.
|
;.
|
||||||
; NOT_CGSCC_NPM: attributes #[[ATTR0]] = { nofree noreturn nosync nounwind readnone }
|
; NOT_CGSCC_NPM: attributes #[[ATTR0:[0-9]+]] = { nofree noreturn nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse noreturn nosync nounwind readonly willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone }
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture readonly %p2) {
|
define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture readonly %p2) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[P1:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa [[TBAA0:![0-9]+]]
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa [[TBAA0:![0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
|
; IS__TUNIT____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
|
||||||
|
@ -60,7 +60,7 @@ define i32 @main() {
|
||||||
; IS__TUNIT____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA5]]
|
; IS__TUNIT____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa [[TBAA5]]
|
||||||
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA5]]
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa [[TBAA5]]
|
||||||
; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA0]]
|
; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa [[TBAA0]]
|
||||||
; IS__TUNIT____-NEXT: call fastcc void @fn() #[[ATTR0]]
|
; IS__TUNIT____-NEXT: call fastcc void @fn(i32* nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) @g) #[[ATTR0]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 0
|
; IS__TUNIT____-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -53,16 +53,32 @@ return: ; preds = %entry
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i32 @vfu2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwind readonly {
|
define internal i32 @vfu2(%struct.MYstr* byval(%struct.MYstr) align 4 %u) nounwind readonly {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@vfu2
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@vfu2
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_MYSTR:%.*]]) align 8 dereferenceable(8) [[U:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
|
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1
|
||||||
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
|
||||||
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0), align 8
|
; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0), align 8
|
||||||
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i32
|
; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = zext i8 [[TMP2]] to i32
|
||||||
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], [[TMP1]]
|
; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], [[TMP1]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[TMP4]]
|
; IS__TUNIT_OPM-NEXT: ret i32 [[TMP4]]
|
||||||
|
;
|
||||||
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@vfu2
|
||||||
|
; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8*
|
||||||
|
; IS__TUNIT_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]], align 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]], align 4
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load i8, i8* getelementptr inbounds ([[STRUCT_MYSTR]], %struct.MYstr* @mystr, i32 0, i32 0), align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = zext i8 [[TMP4]] to i32
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP3]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i32 [[TMP6]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@vfu2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@vfu2
|
||||||
|
@ -86,12 +102,23 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @unions() nounwind {
|
define i32 @unions() nounwind {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@unions
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[RESULT:%.*]] = call i32 @vfu2() #[[ATTR0]]
|
; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nocapture nofree noundef nonnull readonly byval([[STRUCT_MYSTR:%.*]]) align 8 dereferenceable(8) @mystr) #[[ATTR0]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[RESULT]]
|
; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]]
|
||||||
|
;
|
||||||
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
|
||||||
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions
|
||||||
|
; IS__TUNIT_NPM-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 8
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32 [[TMP1]]) #[[ATTR0]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@unions
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@unions
|
||||||
|
@ -227,8 +254,8 @@ entry:
|
||||||
ret i32 %result
|
ret i32 %result
|
||||||
}
|
}
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readonly willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { nofree nosync nounwind readonly willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1:[0-9]+]] = { nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
|
|
|
@ -8,20 +8,37 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
define i64 @fn2() {
|
define i64 @fn2() {
|
||||||
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2
|
||||||
|
; IS__TUNIT_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
|
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR0]]
|
||||||
|
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i64 undef
|
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR0]], !range [[RNG0:![0-9]+]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC_OPM-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
||||||
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
|
; IS__CGSCC_OPM-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
|
||||||
; IS__CGSCC____-NEXT: ret i64 undef
|
; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR1:[0-9]+]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2
|
||||||
|
; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: entry:
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, 0
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%conv = sext i32 undef to i64
|
%conv = sext i32 undef to i64
|
||||||
|
@ -31,7 +48,6 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @fn2b(i32 %arg) {
|
define i64 @fn2b(i32 %arg) {
|
||||||
;
|
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2b
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2b
|
||||||
; IS__TUNIT_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
|
||||||
|
@ -47,24 +63,17 @@ define i64 @fn2b(i32 %arg) {
|
||||||
; IS__TUNIT_NPM-NEXT: entry:
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||||
; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret i64 [[DIV]]
|
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR0]], !range [[RNG0]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2b
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b
|
||||||
; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
; IS__CGSCC____-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
||||||
; IS__CGSCC_OPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
; IS__CGSCC____-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
||||||
; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR1:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]]
|
; IS__CGSCC____-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2b
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32 [[ARG:%.*]]) #[[ATTR0]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i64 [[DIV]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%conv = sext i32 %arg to i64
|
%conv = sext i32 %arg to i64
|
||||||
|
@ -74,23 +83,35 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @fn2c() {
|
define i64 @fn2c() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2c
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i64 42
|
; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR0]]
|
||||||
|
; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
|
||||||
|
;
|
||||||
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2c
|
||||||
|
; IS__TUNIT_NPM-SAME: () #[[ATTR0]] {
|
||||||
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR0]], !range [[RNG0]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2c
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2c
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
|
; IS__CGSCC_OPM-SAME: () #[[ATTR0]] {
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
; IS__CGSCC_OPM-NEXT: entry:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i64 42
|
; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
||||||
|
; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i64 42, 0
|
||||||
|
; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 noundef 42) #[[ATTR1]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i64 [[CALL2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2c
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2c
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
|
; IS__CGSCC_NPM-SAME: () #[[ATTR0]] {
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
; IS__CGSCC_NPM-NEXT: entry:
|
||||||
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = sext i32 undef to i64
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[ADD:%.*]] = add i64 42, 0
|
||||||
; IS__CGSCC_NPM-NEXT: ret i64 42
|
; IS__CGSCC_NPM-NEXT: ret i64 42
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -101,23 +122,21 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i64 @fn1(i64 %p1) {
|
define internal i64 @fn1(i64 %p1) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
|
||||||
; IS__TUNIT_OPM-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: ret i64 [[P1]]
|
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
|
||||||
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i64 [[COND]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
|
||||||
; IS__CGSCC_OPM-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i64 [[P1]]
|
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
|
||||||
;
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____-NEXT: ret i64 [[COND]]
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn1
|
|
||||||
; IS__CGSCC_NPM-SAME: (i64 [[P1:%.*]]) #[[ATTR0]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i64 undef
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp ne i64 %p1, 0
|
%tobool = icmp ne i64 %p1, 0
|
||||||
|
@ -127,8 +146,10 @@ entry:
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__TUNIT_NPM: [[RNG0]] = !{i64 -2147483606, i64 2147483690}
|
||||||
|
;.
|
||||||
|
; IS__CGSCC____: [[RNG0]] = !{i64 -8, i64 43}
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -8,67 +8,37 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
define void @fn2(i32* %P, i1 %C) {
|
define void @fn2(i32* %P, i1 %C) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2
|
||||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
|
||||||
; IS__TUNIT_OPM: for.cond1:
|
; IS__TUNIT____: for.cond1:
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
||||||
; IS__TUNIT_OPM: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT_OPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
||||||
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) #[[ATTR3:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]]) #[[ATTR3:[0-9]+]]
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[FOR_COND1]]
|
; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
|
||||||
; IS__TUNIT_OPM: exit:
|
; IS__TUNIT____: exit:
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
|
||||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br label [[IF_END:%.*]]
|
||||||
; IS__TUNIT_NPM: for.cond1:
|
; IS__CGSCC____: for.cond1:
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
||||||
; IS__TUNIT_NPM: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__TUNIT_NPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
||||||
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[FOR_COND1]]
|
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||||
; IS__TUNIT_NPM: exit:
|
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__CGSCC____: exit:
|
||||||
;
|
; IS__CGSCC____-NEXT: ret void
|
||||||
; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn2
|
|
||||||
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
|
|
||||||
; IS__CGSCC_OPM: for.cond1:
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
|
||||||
; IS__CGSCC_OPM: if.end:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
|
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]]
|
|
||||||
; IS__CGSCC_OPM: exit:
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn2
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
|
|
||||||
; IS__CGSCC_NPM: for.cond1:
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
|
||||||
; IS__CGSCC_NPM: if.end:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]]
|
|
||||||
; IS__CGSCC_NPM: exit:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
@ -87,23 +57,21 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i32 @fn1(i32 %p1) {
|
define internal i32 @fn1(i32 %p1) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
|
||||||
; IS__TUNIT_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32 [[P1]]
|
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||||
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
|
||||||
; IS__CGSCC_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[P1]]
|
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||||
;
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____-NEXT: ret i32 [[COND]]
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn1
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32 [[P1:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 undef
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp ne i32 %p1, 0
|
%tobool = icmp ne i32 %p1, 0
|
||||||
|
@ -113,67 +81,37 @@ entry:
|
||||||
|
|
||||||
define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
|
define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind null_pointer_is_valid
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn_no_null_opt
|
||||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
|
||||||
; IS__TUNIT_OPM: for.cond1:
|
; IS__TUNIT____: for.cond1:
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
||||||
; IS__TUNIT_OPM: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
||||||
; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
||||||
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) #[[ATTR3]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]]) #[[ATTR3]]
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[FOR_COND1]]
|
; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
|
||||||
; IS__TUNIT_OPM: exit:
|
; IS__TUNIT____: exit:
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind null_pointer_is_valid
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn_no_null_opt
|
||||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]]) #[[ATTR1:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br label [[IF_END:%.*]]
|
||||||
; IS__TUNIT_NPM: for.cond1:
|
; IS__CGSCC____: for.cond1:
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
||||||
; IS__TUNIT_NPM: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__TUNIT_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
||||||
; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[FOR_COND1]]
|
; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
||||||
; IS__TUNIT_NPM: exit:
|
; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__CGSCC____: exit:
|
||||||
;
|
; IS__CGSCC____-NEXT: ret void
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt
|
|
||||||
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
|
|
||||||
; IS__CGSCC_OPM: for.cond1:
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
|
||||||
; IS__CGSCC_OPM: if.end:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
|
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]]
|
|
||||||
; IS__CGSCC_OPM: exit:
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
|
|
||||||
; IS__CGSCC_NPM: for.cond1:
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
|
|
||||||
; IS__CGSCC_NPM: if.end:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ], [ null, [[FOR_COND1:%.*]] ]
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[P]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]]
|
|
||||||
; IS__CGSCC_NPM: exit:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br label %if.end
|
br label %if.end
|
||||||
|
@ -192,23 +130,21 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i32 @fn0(i32 %p1) {
|
define internal i32 @fn0(i32 %p1) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn0
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn0
|
||||||
; IS__TUNIT_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32 [[P1]]
|
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||||
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[COND]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn0
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn0
|
||||||
; IS__CGSCC_OPM-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[P1]]
|
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
|
||||||
;
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____-NEXT: ret i32 [[COND]]
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn0
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32 [[P1:%.*]]) #[[ATTR1]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 undef
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%tobool = icmp ne i32 %p1, 0
|
%tobool = icmp ne i32 %p1, 0
|
||||||
|
@ -216,15 +152,12 @@ entry:
|
||||||
ret i32 %cond
|
ret i32 %cond
|
||||||
}
|
}
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind null_pointer_is_valid }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone }
|
; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind null_pointer_is_valid }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
;.
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree norecurse nosync nounwind null_pointer_is_valid }
|
||||||
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind }
|
|
||||||
; IS__CGSCC____: attributes #[[ATTR1:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
|
||||||
; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nofree norecurse nosync nounwind null_pointer_is_valid }
|
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -118,8 +118,8 @@ define dso_local i16 @vararg_tests(i16 %a) {
|
||||||
define internal i16 @vararg_prop(i16 %p1, ...) {
|
define internal i16 @vararg_prop(i16 %p1, ...) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
|
||||||
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], ...) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], ...) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: ret i16 undef
|
; IS__CGSCC____-NEXT: ret i16 7
|
||||||
;
|
;
|
||||||
ret i16 %p1
|
ret i16 %p1
|
||||||
}
|
}
|
||||||
|
@ -127,12 +127,12 @@ define internal i16 @vararg_prop(i16 %p1, ...) {
|
||||||
define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) {
|
define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@vararg_no_prop
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@vararg_no_prop
|
||||||
; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: ret i16 7
|
; IS__TUNIT____-NEXT: ret i16 7
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_no_prop
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_no_prop
|
||||||
; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: ret i16 7
|
; IS__CGSCC____-NEXT: ret i16 7
|
||||||
;
|
;
|
||||||
ret i16 %p1
|
ret i16 %p1
|
||||||
|
|
|
@ -54,7 +54,7 @@ define internal void @bar(i32* nocapture %pc) nounwind readonly {
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
|
; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 536870912 dereferenceable(4294967295) [[PC:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; IS__CGSCC_NPM-NEXT: entry:
|
; IS__CGSCC_NPM-NEXT: entry:
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[INDIRECTGOTO:%.*]]
|
; IS__CGSCC_NPM-NEXT: br label [[INDIRECTGOTO:%.*]]
|
||||||
; IS__CGSCC_NPM: lab0:
|
; IS__CGSCC_NPM: lab0:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
;
|
;
|
||||||
|
@ -42,13 +42,13 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
define internal i32 @cb0(i32 %zero) {
|
define internal i32 @cb0(i32 %zero) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@cb0
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@cb0
|
||||||
; IS__TUNIT____-SAME: (i32 [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32 returned [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i32 0
|
; IS__TUNIT____-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@cb0
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@cb0
|
||||||
; IS__CGSCC____-SAME: (i32 [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32 returned [[ZERO:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: ret i32 0
|
; IS__CGSCC____-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
; PR36485
|
; PR36485
|
||||||
|
@ -8,71 +8,40 @@
|
||||||
|
|
||||||
declare i32 @external()
|
declare i32 @external()
|
||||||
|
|
||||||
|
; FIXME: We should not return undef here.
|
||||||
define i8* @start(i8 %v) {
|
define i8* @start(i8 %v) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@start
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@start
|
||||||
; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) {
|
; IS__TUNIT____-SAME: (i8 [[V:%.*]]) {
|
||||||
; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
; IS__TUNIT____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||||
; IS__TUNIT_OPM: true:
|
; IS__TUNIT____: true:
|
||||||
; IS__TUNIT_OPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
|
; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
|
||||||
; IS__TUNIT_OPM-NEXT: ret i8* [[CA]]
|
; IS__TUNIT____-NEXT: ret i8* [[CA]]
|
||||||
; IS__TUNIT_OPM: false:
|
; IS__TUNIT____: false:
|
||||||
; IS__TUNIT_OPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
; IS__TUNIT____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
||||||
; IS__TUNIT_OPM: c2_true:
|
; IS__TUNIT____: c2_true:
|
||||||
; IS__TUNIT_OPM-NEXT: ret i8* null
|
; IS__TUNIT____-NEXT: ret i8* null
|
||||||
; IS__TUNIT_OPM: c2_false:
|
; IS__TUNIT____: c2_false:
|
||||||
; IS__TUNIT_OPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
; IS__TUNIT____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
||||||
; IS__TUNIT_OPM-NEXT: ret i8* [[CA2]]
|
; IS__TUNIT____-NEXT: ret i8* [[CA2]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@start
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@start
|
||||||
; IS__TUNIT_NPM-SAME: (i8 [[V:%.*]]) {
|
; IS__CGSCC____-SAME: (i8 [[V:%.*]]) {
|
||||||
; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
; IS__CGSCC____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
||||||
; IS__TUNIT_NPM: true:
|
; IS__CGSCC____: true:
|
||||||
; IS__TUNIT_NPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 undef)
|
; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
|
||||||
; IS__TUNIT_NPM-NEXT: ret i8* [[CA]]
|
; IS__CGSCC____-NEXT: ret i8* [[CA]]
|
||||||
; IS__TUNIT_NPM: false:
|
; IS__CGSCC____: false:
|
||||||
; IS__TUNIT_NPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
; IS__CGSCC____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
||||||
; IS__TUNIT_NPM: c2_true:
|
; IS__CGSCC____: c2_true:
|
||||||
; IS__TUNIT_NPM-NEXT: ret i8* null
|
; IS__CGSCC____-NEXT: ret i8* undef
|
||||||
; IS__TUNIT_NPM: c2_false:
|
; IS__CGSCC____: c2_false:
|
||||||
; IS__TUNIT_NPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
||||||
; IS__TUNIT_NPM-NEXT: ret i8* [[CA2]]
|
; IS__CGSCC____-NEXT: ret i8* [[CA2]]
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@start
|
|
||||||
; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) {
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
||||||
; IS__CGSCC_OPM: true:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* [[CA]]
|
|
||||||
; IS__CGSCC_OPM: false:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
|
||||||
; IS__CGSCC_OPM: c2_true:
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* undef
|
|
||||||
; IS__CGSCC_OPM: c2_false:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* [[CA2]]
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@start
|
|
||||||
; IS__CGSCC_NPM-SAME: (i8 [[V:%.*]]) {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
|
|
||||||
; IS__CGSCC_NPM: true:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 undef)
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* [[CA]]
|
|
||||||
; IS__CGSCC_NPM: false:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]]
|
|
||||||
; IS__CGSCC_NPM: c2_true:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* undef
|
|
||||||
; IS__CGSCC_NPM: c2_false:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* [[CA2]]
|
|
||||||
;
|
;
|
||||||
%c1 = icmp eq i8 %v, 0
|
%c1 = icmp eq i8 %v, 0
|
||||||
br i1 %c1, label %true, label %false
|
br i1 %c1, label %true, label %false
|
||||||
|
@ -92,17 +61,11 @@ c2_false:
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i8* @side_effects(i8 %v) {
|
define internal i8* @side_effects(i8 %v) {
|
||||||
; IS________OPM-LABEL: define {{[^@]+}}@side_effects
|
; CHECK-LABEL: define {{[^@]+}}@side_effects
|
||||||
; IS________OPM-SAME: (i8 [[V:%.*]]) {
|
; CHECK-SAME: (i8 [[V:%.*]]) {
|
||||||
; IS________OPM-NEXT: [[I1:%.*]] = call i32 @external()
|
; CHECK-NEXT: [[I1:%.*]] = call i32 @external()
|
||||||
; IS________OPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
|
; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
|
||||||
; IS________OPM-NEXT: ret i8* [[CA]]
|
; CHECK-NEXT: ret i8* [[CA]]
|
||||||
;
|
|
||||||
; IS________NPM-LABEL: define {{[^@]+}}@side_effects
|
|
||||||
; IS________NPM-SAME: (i8 [[V:%.*]]) {
|
|
||||||
; IS________NPM-NEXT: [[I1:%.*]] = call i32 @external()
|
|
||||||
; IS________NPM-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 noundef 0)
|
|
||||||
; IS________NPM-NEXT: ret i8* [[CA]]
|
|
||||||
;
|
;
|
||||||
%i1 = call i32 @external()
|
%i1 = call i32 @external()
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ define dso_local i32 @main() {
|
||||||
; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
|
; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
|
||||||
; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
|
; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef)
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree readnone align 536870912 undef)
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef)
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" undef)
|
||||||
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
|
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
|
||||||
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
|
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
|
||||||
; IS__TUNIT____-NEXT: ret i32 0
|
; IS__TUNIT____-NEXT: ret i32 0
|
||||||
|
@ -51,7 +51,7 @@ define dso_local i32 @main() {
|
||||||
; IS__CGSCC____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
|
; IS__CGSCC____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
|
||||||
; IS__CGSCC____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
|
; IS__CGSCC____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree noundef readnone align 536870912 null)
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @foo, i8* noalias nocapture nofree noundef readnone align 536870912 null)
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @bar, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
|
||||||
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
|
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @baz, i8* noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
|
||||||
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
|
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* noundef nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias nocapture noundef align 536870912 null, i8* (i8*)* noundef nonnull @buz, i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC2]])
|
||||||
; IS__CGSCC____-NEXT: ret i32 0
|
; IS__CGSCC____-NEXT: ret i32 0
|
||||||
|
@ -72,13 +72,13 @@ declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*,
|
||||||
define internal i8* @foo(i8* %arg) {
|
define internal i8* @foo(i8* %arg) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
|
||||||
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree readnone align 536870912 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i8* null
|
; IS__TUNIT____-NEXT: ret i8* null
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
|
||||||
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree readnone align 536870912 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: ret i8* null
|
; IS__CGSCC____-NEXT: ret i8* null
|
||||||
;
|
;
|
||||||
|
@ -89,13 +89,13 @@ entry:
|
||||||
define internal i8* @bar(i8* %arg) {
|
define internal i8* @bar(i8* %arg) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
|
||||||
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
|
; IS__TUNIT____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
|
||||||
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
|
; IS__CGSCC____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
|
||||||
;
|
;
|
||||||
|
|
|
@ -20,33 +20,19 @@ define internal i32* @incdec(i1 %C, i32* %V) {
|
||||||
; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4
|
; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[V]]
|
; IS__TUNIT____-NEXT: ret i32* [[V]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@incdec
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec
|
||||||
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
|
; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; IS__CGSCC_OPM: T:
|
; IS__CGSCC____: T:
|
||||||
; IS__CGSCC_OPM-NEXT: [[X1:%.*]] = add i32 [[X]], 1
|
; IS__CGSCC____-NEXT: [[X1:%.*]] = add i32 [[X]], 1
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[X1]], i32* [[V]], align 4
|
; IS__CGSCC____-NEXT: store i32 [[X1]], i32* [[V]], align 4
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32* [[V]]
|
; IS__CGSCC____-NEXT: ret i32* [[V]]
|
||||||
; IS__CGSCC_OPM: F:
|
; IS__CGSCC____: F:
|
||||||
; IS__CGSCC_OPM-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
|
; IS__CGSCC____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[X2]], i32* [[V]], align 4
|
; IS__CGSCC____-NEXT: store i32 [[X2]], i32* [[V]], align 4
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32* [[V]]
|
; IS__CGSCC____-NEXT: ret i32* [[V]]
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@incdec
|
|
||||||
; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
|
||||||
; IS__CGSCC_NPM: T:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[X1:%.*]] = add i32 [[X]], 1
|
|
||||||
; IS__CGSCC_NPM-NEXT: store i32 [[X1]], i32* [[V]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32* undef
|
|
||||||
; IS__CGSCC_NPM: F:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
|
|
||||||
; IS__CGSCC_NPM-NEXT: store i32 [[X2]], i32* [[V]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32* undef
|
|
||||||
;
|
;
|
||||||
%X = load i32, i32* %V
|
%X = load i32, i32* %V
|
||||||
br i1 %C, label %T, label %F
|
br i1 %C, label %T, label %F
|
||||||
|
@ -88,81 +74,43 @@ define internal { i32, i32 } @foo(i32 %A, i32 %B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
|
define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
|
||||||
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
|
||||||
; IS__TUNIT_OPM-NEXT: [[Q:%.*]] = alloca i32, align 4
|
; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2]]
|
||||||
; IS__TUNIT_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR1]]
|
; IS__TUNIT____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR1]]
|
||||||
; IS__TUNIT_OPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
; IS__TUNIT____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
||||||
; IS__TUNIT_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR1]]
|
; IS__TUNIT____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR1]]
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[OK:%.*]]
|
; IS__TUNIT____-NEXT: br label [[OK:%.*]]
|
||||||
; IS__TUNIT_OPM: OK:
|
; IS__TUNIT____: OK:
|
||||||
; IS__TUNIT_OPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
; IS__TUNIT____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
||||||
; IS__TUNIT_OPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
; IS__TUNIT____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 [[Z]], i32* [[W]], align 4
|
; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[W]], align 4
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[RET:%.*]]
|
; IS__TUNIT____-NEXT: br label [[RET:%.*]]
|
||||||
; IS__TUNIT_OPM: LPAD:
|
; IS__TUNIT____: LPAD:
|
||||||
; IS__TUNIT_OPM-NEXT: unreachable
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
; IS__TUNIT_OPM: RET:
|
; IS__TUNIT____: RET:
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
|
||||||
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] personality i32 (...)* @__gxx_personality_v0 {
|
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
|
||||||
; IS__TUNIT_NPM-NEXT: [[Q:%.*]] = alloca i32, align 4
|
; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR1]]
|
; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
||||||
; IS__TUNIT_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR1]]
|
; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR4:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[OK:%.*]]
|
; IS__CGSCC____-NEXT: br label [[OK:%.*]]
|
||||||
; IS__TUNIT_NPM: OK:
|
; IS__CGSCC____: OK:
|
||||||
; IS__TUNIT_NPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
; IS__CGSCC____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
||||||
; IS__TUNIT_NPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
; IS__CGSCC____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 [[Z]], i32* [[Q]], align 4
|
; IS__CGSCC____-NEXT: store i32 [[Z]], i32* [[W]], align 4
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[RET:%.*]]
|
; IS__CGSCC____-NEXT: br label [[RET:%.*]]
|
||||||
; IS__TUNIT_NPM: LPAD:
|
; IS__CGSCC____: LPAD:
|
||||||
; IS__TUNIT_NPM-NEXT: unreachable
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
; IS__TUNIT_NPM: RET:
|
; IS__CGSCC____: RET:
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller
|
|
||||||
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[Q:%.*]] = alloca i32, align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR4:[0-9]+]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[OK:%.*]]
|
|
||||||
; IS__CGSCC_OPM: OK:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[Z]], i32* [[W]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[RET:%.*]]
|
|
||||||
; IS__CGSCC_OPM: LPAD:
|
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_OPM: RET:
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller
|
|
||||||
; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR1]] personality i32 (...)* @__gxx_personality_v0 {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[Q:%.*]] = alloca i32, align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[W:%.*]] = call i32* @incdec(i1 [[C]], i32* noalias nofree noundef nonnull align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q]]) #[[ATTR2:[0-9]+]]
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 noundef 1, i32 noundef 2) #[[ATTR3:[0-9]+]]
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 noundef 3, i32 noundef 4) #[[ATTR4:[0-9]+]]
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[OK:%.*]]
|
|
||||||
; IS__CGSCC_NPM: OK:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
|
|
||||||
; IS__CGSCC_NPM-NEXT: store i32 [[Z]], i32* [[Q]], align 4
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[RET:%.*]]
|
|
||||||
; IS__CGSCC_NPM: LPAD:
|
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_NPM: RET:
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
%Q = alloca i32
|
%Q = alloca i32
|
||||||
;; Call incdec to see if %W is properly replaced by %Q
|
;; Call incdec to see if %W is properly replaced by %Q
|
||||||
|
@ -194,11 +142,11 @@ declare i32 @__gxx_personality_v0(...)
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { argmemonly nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2:[0-9]+]] = { nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { argmemonly nofree norecurse nosync nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { argmemonly nofree norecurse nosync nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR2:[0-9]+]] = { nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR3:[0-9]+]] = { readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR3]] = { readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR4]] = { nounwind readnone willreturn }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
@ -108,14 +108,22 @@ define i32* @test5_2() {
|
||||||
; TEST 6
|
; TEST 6
|
||||||
; SCC
|
; SCC
|
||||||
define i32* @test6_1() #0 {
|
define i32* @test6_1() #0 {
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
|
; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test6_1
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
|
; IS__TUNIT____-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
; IS__TUNIT____-NEXT: [[RET:%.*]] = tail call i32* @test6_2() #[[ATTR11:[0-9]+]]
|
||||||
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
|
||||||
|
; IS__CGSCC_OPM-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
|
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() #[[ATTR13:[0-9]+]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
|
; IS__CGSCC_NPM-SAME: () #[[ATTR1:[0-9]+]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call i32* @test6_2() #[[ATTR12:[0-9]+]]
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
; IS__CGSCC_NPM-NEXT: unreachable
|
||||||
;
|
;
|
||||||
%ret = tail call i32* @test6_2()
|
%ret = tail call i32* @test6_2()
|
||||||
|
@ -123,14 +131,22 @@ define i32* @test6_1() #0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32* @test6_2() #0 {
|
define i32* @test6_2() #0 {
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
|
; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test6_2
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR1]] {
|
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
; IS__TUNIT____-NEXT: [[RET:%.*]] = tail call i32* @test6_1() #[[ATTR11]]
|
||||||
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
|
||||||
|
; IS__CGSCC_OPM-SAME: () #[[ATTR1]] {
|
||||||
|
; IS__CGSCC_OPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() #[[ATTR13]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
|
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[RET:%.*]] = tail call i32* @test6_1() #[[ATTR12]]
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
; IS__CGSCC_NPM-NEXT: unreachable
|
||||||
;
|
;
|
||||||
%ret = tail call i32* @test6_1()
|
%ret = tail call i32* @test6_1()
|
||||||
|
@ -157,14 +173,23 @@ define i32* @test6_2() #0 {
|
||||||
|
|
||||||
; Function Attrs: nounwind readnone ssp uwtable
|
; Function Attrs: nounwind readnone ssp uwtable
|
||||||
define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
|
define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
|
||||||
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
||||||
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
|
||||||
|
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
||||||
|
; IS__TUNIT____-NEXT: br label [[TMP3:%.*]]
|
||||||
|
; IS__TUNIT____: 2:
|
||||||
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
|
; IS__TUNIT____: 3:
|
||||||
|
; IS__TUNIT____-NEXT: ret i8* [[TMP0]]
|
||||||
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
|
||||||
; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
; IS__CGSCC_OPM-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
|
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
|
||||||
; IS__CGSCC_OPM: 2:
|
; IS__CGSCC_OPM: 2:
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
; IS__CGSCC_OPM: 3:
|
; IS__CGSCC_OPM: 3:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* undef
|
; IS__CGSCC_OPM-NEXT: ret i8* @a1
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
|
||||||
|
@ -195,22 +220,24 @@ define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
|
||||||
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
|
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
|
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
|
||||||
; IS__CGSCC_OPM: 2:
|
; IS__CGSCC_OPM: 2:
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
|
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nonnull readnone align 536870912 dereferenceable(4294967295) undef)
|
||||||
; IS__CGSCC_OPM: 3:
|
; IS__CGSCC_OPM-NEXT: br label [[TMP5:%.*]]
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_OPM: 4:
|
; IS__CGSCC_OPM: 4:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* undef
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
|
; IS__CGSCC_OPM: 5:
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i8* [[TMP3]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
|
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2
|
||||||
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
|
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
|
||||||
; IS__CGSCC_NPM: 2:
|
; IS__CGSCC_NPM: 2:
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[TMP4:%.*]]
|
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1()
|
||||||
; IS__CGSCC_NPM: 3:
|
; IS__CGSCC_NPM-NEXT: br label [[TMP5:%.*]]
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_NPM: 4:
|
; IS__CGSCC_NPM: 4:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* undef
|
; IS__CGSCC_NPM-NEXT: unreachable
|
||||||
|
; IS__CGSCC_NPM: 5:
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i8* @a1
|
||||||
;
|
;
|
||||||
%2 = icmp eq i8* %0, null
|
%2 = icmp eq i8* %0, null
|
||||||
br i1 %2, label %5, label %3
|
br i1 %2, label %5, label %3
|
||||||
|
@ -267,7 +294,8 @@ define align 4 i8* @test7() #0 {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: ret i8* @a1
|
; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1) #[[ATTR9:[0-9]+]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i8* [[C]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
|
||||||
|
@ -283,12 +311,12 @@ define align 4 i8* @test7() #0 {
|
||||||
define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
|
define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1b
|
||||||
; IS__CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
|
; IS__CGSCC_OPM-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
|
; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
|
||||||
; IS__CGSCC_OPM: 2:
|
; IS__CGSCC_OPM: 2:
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
; IS__CGSCC_OPM: 3:
|
; IS__CGSCC_OPM: 3:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* undef
|
; IS__CGSCC_OPM-NEXT: ret i8* @a1
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1b
|
||||||
|
@ -321,22 +349,24 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
|
||||||
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] {
|
; IS__CGSCC_OPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR3]] {
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
|
; IS__CGSCC_OPM-NEXT: br label [[TMP2:%.*]]
|
||||||
; IS__CGSCC_OPM: 2:
|
; IS__CGSCC_OPM: 2:
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
|
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nonnull readnone align 536870912 dereferenceable(4294967295) undef)
|
||||||
; IS__CGSCC_OPM: 3:
|
; IS__CGSCC_OPM-NEXT: br label [[TMP5:%.*]]
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_OPM: 4:
|
; IS__CGSCC_OPM: 4:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* undef
|
; IS__CGSCC_OPM-NEXT: unreachable
|
||||||
|
; IS__CGSCC_OPM: 5:
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i8* [[TMP3]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
|
; IS__CGSCC_NPM: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f2b
|
||||||
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
|
; IS__CGSCC_NPM-SAME: (i8* nonnull readnone [[TMP0:%.*]]) local_unnamed_addr #[[ATTR2]] {
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
|
; IS__CGSCC_NPM-NEXT: br label [[TMP2:%.*]]
|
||||||
; IS__CGSCC_NPM: 2:
|
; IS__CGSCC_NPM: 2:
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[TMP4:%.*]]
|
; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = tail call i8* @f1b()
|
||||||
; IS__CGSCC_NPM: 3:
|
; IS__CGSCC_NPM-NEXT: br label [[TMP5:%.*]]
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
; IS__CGSCC_NPM: 4:
|
; IS__CGSCC_NPM: 4:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* undef
|
; IS__CGSCC_NPM-NEXT: unreachable
|
||||||
|
; IS__CGSCC_NPM: 5:
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i8* @a1
|
||||||
;
|
;
|
||||||
%2 = icmp eq i8* %0, null
|
%2 = icmp eq i8* %0, null
|
||||||
br i1 %2, label %5, label %3
|
br i1 %2, label %5, label %3
|
||||||
|
@ -1090,7 +1120,7 @@ end:
|
||||||
define i64 @ptr2int(i32* %p) {
|
define i64 @ptr2int(i32* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int
|
||||||
; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]]) #[[ATTR9]] {
|
||||||
; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
|
; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
|
||||||
; IS__TUNIT____-NEXT: ret i64 [[P2I]]
|
; IS__TUNIT____-NEXT: ret i64 [[P2I]]
|
||||||
;
|
;
|
||||||
|
@ -1239,7 +1269,7 @@ define i32 @musttail_caller_1(i32* %p) {
|
||||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
||||||
; IS__CGSCC_OPM: mt:
|
; IS__CGSCC_OPM: mt:
|
||||||
; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]]
|
; IS__CGSCC_OPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR14:[0-9]+]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[V]]
|
; IS__CGSCC_OPM-NEXT: ret i32 [[V]]
|
||||||
; IS__CGSCC_OPM: exit:
|
; IS__CGSCC_OPM: exit:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 0
|
; IS__CGSCC_OPM-NEXT: ret i32 0
|
||||||
|
@ -1250,7 +1280,7 @@ define i32 @musttail_caller_1(i32* %p) {
|
||||||
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
|
||||||
; IS__CGSCC_NPM: mt:
|
; IS__CGSCC_NPM: mt:
|
||||||
; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR12:[0-9]+]]
|
; IS__CGSCC_NPM-NEXT: [[V:%.*]] = musttail call i32 @musttail_callee_1(i32* nocapture nofree noundef nonnull readonly dereferenceable(4) [[P]]) #[[ATTR13:[0-9]+]]
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 [[V]]
|
; IS__CGSCC_NPM-NEXT: ret i32 [[V]]
|
||||||
; IS__CGSCC_NPM: exit:
|
; IS__CGSCC_NPM: exit:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 0
|
; IS__CGSCC_NPM-NEXT: ret i32 0
|
||||||
|
@ -1348,7 +1378,7 @@ attributes #1 = { uwtable noinline }
|
||||||
attributes #2 = { null_pointer_is_valid }
|
attributes #2 = { null_pointer_is_valid }
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone uwtable }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nounwind }
|
||||||
; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind }
|
; IS__TUNIT____: attributes #[[ATTR3]] = { nofree nosync nounwind }
|
||||||
; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind readonly willreturn }
|
; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind readonly willreturn }
|
||||||
|
@ -1358,9 +1388,10 @@ attributes #2 = { null_pointer_is_valid }
|
||||||
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR9]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind readonly willreturn }
|
; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind readonly willreturn }
|
||||||
|
; IS__TUNIT____: attributes #[[ATTR11]] = { nofree noreturn nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone uwtable }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { noinline nounwind uwtable }
|
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { noinline nounwind uwtable }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind }
|
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { nounwind }
|
||||||
|
@ -1372,10 +1403,11 @@ attributes #2 = { null_pointer_is_valid }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
; IS__CGSCC_OPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind readonly willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind readonly willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR13]] = { readonly willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR13]] = { nofree noreturn nosync nounwind readnone }
|
||||||
|
; IS__CGSCC_OPM: attributes #[[ATTR14]] = { readonly willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree noinline noreturn nosync nounwind readnone uwtable }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { noinline nounwind uwtable }
|
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { noinline nounwind uwtable }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nounwind }
|
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nounwind }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind }
|
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind }
|
||||||
|
@ -1386,5 +1418,6 @@ attributes #2 = { null_pointer_is_valid }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
; IS__CGSCC_NPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readonly willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR11]] = { nofree norecurse nosync nounwind readonly willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR12]] = { readonly willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR12]] = { nofree noreturn nosync nounwind readnone }
|
||||||
|
; IS__CGSCC_NPM: attributes #[[ATTR13]] = { readonly willreturn }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -68,10 +68,10 @@ define i32 @test(i32 %0, i32 %1) #0 {
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
|
||||||
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
|
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
|
||||||
; CHECK: 4:
|
; CHECK: 4:
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
||||||
; CHECK-NEXT: br label [[TMP8:%.*]]
|
; CHECK-NEXT: br label [[TMP8:%.*]]
|
||||||
; CHECK: 6:
|
; CHECK: 6:
|
||||||
; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
; CHECK-NEXT: [[TMP7:%.*]] = call i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
||||||
; CHECK-NEXT: br label [[TMP8]]
|
; CHECK-NEXT: br label [[TMP8]]
|
||||||
; CHECK: 8:
|
; CHECK: 8:
|
||||||
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
|
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
|
||||||
|
|
|
@ -68,10 +68,10 @@ define i32 @test(i32 %0, i32 %1) #0 {
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
|
||||||
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
|
; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP6:%.*]]
|
||||||
; CHECK: 4:
|
; CHECK: 4:
|
||||||
; CHECK-NEXT: [[TMP5:%.*]] = call noundef i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
; CHECK-NEXT: [[TMP5:%.*]] = call i32 @test_range1(i32 [[TMP0]]) #[[ATTR1:[0-9]+]], !range [[RNG0:![0-9]+]]
|
||||||
; CHECK-NEXT: br label [[TMP8:%.*]]
|
; CHECK-NEXT: br label [[TMP8:%.*]]
|
||||||
; CHECK: 6:
|
; CHECK: 6:
|
||||||
; CHECK-NEXT: [[TMP7:%.*]] = call noundef i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
; CHECK-NEXT: [[TMP7:%.*]] = call i32 @test_range2(i32 [[TMP0]]) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
||||||
; CHECK-NEXT: br label [[TMP8]]
|
; CHECK-NEXT: br label [[TMP8]]
|
||||||
; CHECK: 8:
|
; CHECK: 8:
|
||||||
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
|
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP5]], [[TMP4]] ], [ [[TMP7]], [[TMP6]] ]
|
||||||
|
@ -94,12 +94,16 @@ define i32 @test(i32 %0, i32 %1) #0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_pcheck1(i32 %0) #0 {
|
define i32 @test_pcheck1(i32 %0) #0 {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test_pcheck1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck1
|
||||||
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]]
|
; IS__TUNIT____-NEXT: ret i32 1
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
|
;
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck1
|
||||||
; CHECK-NEXT: ret i32 [[TMP4]]
|
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2:![0-9]+]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], 101
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_____ENABLED-LABEL: define {{[^@]+}}@test_pcheck1
|
; IS__TUNIT_____ENABLED-LABEL: define {{[^@]+}}@test_pcheck1
|
||||||
; IS__TUNIT_____ENABLED-SAME: (i32 [[TMP0:%.*]])
|
; IS__TUNIT_____ENABLED-SAME: (i32 [[TMP0:%.*]])
|
||||||
|
@ -111,12 +115,16 @@ define i32 @test_pcheck1(i32 %0) #0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_pcheck2(i32 %0) #0 {
|
define i32 @test_pcheck2(i32 %0) #0 {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test_pcheck2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_pcheck2
|
||||||
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
|
; IS__TUNIT____-NEXT: ret i32 1
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
|
;
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_pcheck2
|
||||||
; CHECK-NEXT: ret i32 [[TMP4]]
|
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 99
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
|
||||||
;
|
;
|
||||||
%2 = call i32 @test(i32 %0, i32 0)
|
%2 = call i32 @test(i32 %0, i32 0)
|
||||||
%3 = icmp sgt i32 %2, 99
|
%3 = icmp sgt i32 %2, 99
|
||||||
|
@ -125,12 +133,19 @@ define i32 @test_pcheck2(i32 %0) #0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_ncheck1(i32 %0) #0 {
|
define i32 @test_ncheck1(i32 %0) #0 {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test_ncheck1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck1
|
||||||
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]]
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG0]]
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
; CHECK-NEXT: ret i32 [[TMP4]]
|
; IS__TUNIT____-NEXT: ret i32 [[TMP4]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck1
|
||||||
|
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 1) #[[ATTR1]], !range [[RNG2]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 50
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
|
||||||
;
|
;
|
||||||
%2 = call i32 @test(i32 %0, i32 1)
|
%2 = call i32 @test(i32 %0, i32 1)
|
||||||
%3 = icmp sgt i32 %2, 50
|
%3 = icmp sgt i32 %2, 50
|
||||||
|
@ -139,12 +154,19 @@ define i32 @test_ncheck1(i32 %0) #0 {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test_ncheck2(i32 %0) #0 {
|
define i32 @test_ncheck2(i32 %0) #0 {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test_ncheck2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_ncheck2
|
||||||
; CHECK-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG1]]
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
|
||||||
; CHECK-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
; IS__TUNIT____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
; CHECK-NEXT: ret i32 [[TMP4]]
|
; IS__TUNIT____-NEXT: ret i32 [[TMP4]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_ncheck2
|
||||||
|
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = call i32 @test(i32 [[TMP0]], i32 noundef 0) #[[ATTR1]], !range [[RNG2]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 150
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i1 [[TMP3]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP4]]
|
||||||
;
|
;
|
||||||
%2 = call i32 @test(i32 %0, i32 0)
|
%2 = call i32 @test(i32 %0, i32 0)
|
||||||
%3 = icmp sgt i32 %2, 150
|
%3 = icmp sgt i32 %2, 150
|
||||||
|
@ -163,7 +185,10 @@ attributes #0 = { noinline nounwind sspstrong uwtable}
|
||||||
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong uwtable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone sspstrong uwtable willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { readnone willreturn }
|
||||||
;.
|
;.
|
||||||
; CHECK: [[RNG0]] = !{i32 0, i32 101}
|
; IS__TUNIT____: [[RNG0]] = !{i32 0, i32 101}
|
||||||
; CHECK: [[RNG1]] = !{i32 100, i32 201}
|
; IS__TUNIT____: [[RNG1]] = !{i32 100, i32 201}
|
||||||
; CHECK: [[RNG2]] = !{i32 0, i32 201}
|
;.
|
||||||
|
; IS__CGSCC____: [[RNG0]] = !{i32 0, i32 101}
|
||||||
|
; IS__CGSCC____: [[RNG1]] = !{i32 100, i32 201}
|
||||||
|
; IS__CGSCC____: [[RNG2]] = !{i32 0, i32 201}
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -64,9 +64,19 @@ define i32 @test2(i32 %unknown, i32 %b) {
|
||||||
; we need to look into this again. For the purpose of making some progress we take this regression
|
; we need to look into this again. For the purpose of making some progress we take this regression
|
||||||
; for now, call site contexts are not on by default anyway (yet).
|
; for now, call site contexts are not on by default anyway (yet).
|
||||||
define i32 @test1_pcheck(i32 %unknown) {
|
define i32 @test1_pcheck(i32 %unknown) {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test1_pcheck
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_pcheck
|
||||||
; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: ret i32 1
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1:![0-9]+]]
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_pcheck
|
||||||
|
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 90
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
||||||
;
|
;
|
||||||
%1 = call i32 @test1(i32 %unknown, i32 20)
|
%1 = call i32 @test1(i32 %unknown, i32 20)
|
||||||
%2 = icmp sle i32 %1, 90
|
%2 = icmp sle i32 %1, 90
|
||||||
|
@ -75,9 +85,19 @@ define i32 @test1_pcheck(i32 %unknown) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test2_pcheck(i32 %unknown) {
|
define i32 @test2_pcheck(i32 %unknown) {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test2_pcheck
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_pcheck
|
||||||
; CHECK-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; CHECK-NEXT: ret i32 1
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_pcheck
|
||||||
|
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 20
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
||||||
;
|
;
|
||||||
%1 = call i32 @test2(i32 %unknown, i32 20)
|
%1 = call i32 @test2(i32 %unknown, i32 20)
|
||||||
%2 = icmp sge i32 %1, 20
|
%2 = icmp sge i32 %1, 20
|
||||||
|
@ -90,14 +110,14 @@ define i32 @test2_pcheck(i32 %unknown) {
|
||||||
define i32 @test1_ncheck(i32 %unknown) {
|
define i32 @test1_ncheck(i32 %unknown) {
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_ncheck
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test1_ncheck
|
||||||
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1:![0-9]+]]
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG1]]
|
||||||
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
|
||||||
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_ncheck
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1_ncheck
|
||||||
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1:![0-9]+]]
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test1(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG1]]
|
||||||
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sle i32 [[TMP1]], 10
|
||||||
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
||||||
|
@ -111,14 +131,14 @@ define i32 @test1_ncheck(i32 %unknown) {
|
||||||
define i32 @test2_ncheck(i32 %unknown) {
|
define i32 @test2_ncheck(i32 %unknown) {
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_ncheck
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_ncheck
|
||||||
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR0]], !range [[RNG2]]
|
||||||
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
|
||||||
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
; IS__TUNIT____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
; IS__TUNIT____-NEXT: ret i32 [[TMP3]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_ncheck
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_ncheck
|
||||||
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32 [[UNKNOWN:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2:![0-9]+]]
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @test2(i32 [[UNKNOWN]], i32 noundef 20) #[[ATTR1]], !range [[RNG2]]
|
||||||
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp sge i32 [[TMP1]], 30
|
||||||
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
; IS__CGSCC____-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
; IS__CGSCC____-NEXT: ret i32 [[TMP3]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=12 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=12 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -53,32 +53,30 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
|
|
||||||
; GRAPH: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state Live[#BB 4/4][#TBEP 0][#KDE 1]
|
; GRAPH: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state Live[#BB 4/4][#TBEP 0][#KDE 1]
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state not-simple
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAWillReturn] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-noreturn
|
; GRAPH-NEXT: [AAWillReturn] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-noreturn
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAUndefinedBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state undefined-behavior
|
; GRAPH-NEXT: [AAUndefinedBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state undefined-behavior
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state not-simple
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoUndef] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state may-undef-or-poison
|
; GRAPH-NEXT: [AANoUndef] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state may-undef-or-poison
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAReturnedValues] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state returns(#3)
|
; GRAPH-NEXT: [AAReturnedValues] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state returns(#3)[#UC: 1]
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
|
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
||||||
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
|
||||||
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoSync] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
|
; GRAPH-NEXT: [AANoSync] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nosync
|
||||||
; GRAPH-NEXT: updates [AANoSync] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
|
; GRAPH-NEXT: updates [AANoSync] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nosync
|
||||||
|
@ -86,7 +84,7 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state not-simple
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state range(32)<full-set / full-set>
|
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %2 = load i32, i32* %0, align 4' at position {flt: [@-1]} with state range(32)<full-set / full-set>
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
|
@ -94,6 +92,8 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' br i1 %3, label %4, label %7' at position {flt: [@-1]} with state assumed-live
|
||||||
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
|
; GRAPH-NEXT: [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
|
||||||
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
|
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
|
||||||
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
|
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state nofree
|
||||||
|
@ -105,27 +105,28 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-NEXT: [AANoRecurse] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-recurse
|
; GRAPH-NEXT: [AANoRecurse] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state may-recurse
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
|
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
|
||||||
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
||||||
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
||||||
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
||||||
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state readonly
|
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
|
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
|
||||||
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
||||||
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAHeapToStack] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state [H2S] Mallocs Good/Bad: 0/0
|
; GRAPH-NEXT: [AAHeapToStack] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state [H2S] Mallocs Good/Bad: 0/1
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state not-simple
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
|
; GRAPH-NEXT: [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
|
||||||
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
|
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
|
||||||
|
@ -174,15 +175,11 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
; GRAPH-NEXT: [AANoUnwind] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nounwind
|
||||||
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
|
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
|
||||||
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
|
|
||||||
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
|
; GRAPH-NEXT: updates [AANoUnwind] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nounwind
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
; GRAPH-NEXT: [AAMemoryBehavior] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state readonly
|
||||||
; GRAPH-NEXT: updates [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state assumed-live
|
|
||||||
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
|
; GRAPH-NEXT: updates [AAMemoryBehavior] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state readonly
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state not-simple
|
|
||||||
; GRAPH-EMPTY:
|
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state simplified
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state simplified
|
||||||
|
@ -192,7 +189,6 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-NEXT: [AANoCapture] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: [AANoCapture] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
||||||
; GRAPH-NEXT: updates [AANoCapture] for CtxI ' %2 = load i32, i32* %0, align 4' at position {arg: [@0]} with state assumed not-captured-maybe-returned
|
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoAlias] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state may-alias
|
; GRAPH-NEXT: [AANoAlias] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state may-alias
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
|
@ -205,20 +201,22 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state range(1)<full-set / full-set>
|
; GRAPH-NEXT: [AAValueConstantRange] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state range(1)<full-set / full-set>
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI <<null inst>> at position {flt: [@-1]} with state not-simple
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI <<null inst>> at position {flt: [@-1]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueConstantRange] for CtxI <<null inst>> at position {flt: [@-1]} with state range(32)<[0,1) / [0,1)>
|
; GRAPH-NEXT: [AAValueConstantRange] for CtxI <<null inst>> at position {flt: [@-1]} with state range(32)<[0,1) / [0,1)>
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state set-state(< {full-set} >)
|
; GRAPH-NEXT: [AAPotentialValues] for CtxI ' %3 = icmp eq i32 %2, 0' at position {flt: [@-1]} with state set-state(< {full-set} >)
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' br i1 %3, label %4, label %7' at position {flt: [@-1]} with state assumed-live
|
|
||||||
; GRAPH-EMPTY:
|
|
||||||
; GRAPH-NEXT: [AANoReturn] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-return
|
; GRAPH-NEXT: [AANoReturn] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-return
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state not-simple
|
; GRAPH-NEXT: [AANoAlias] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-alias
|
||||||
|
; GRAPH-EMPTY:
|
||||||
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state simplified
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoUndef] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-undef-or-poison
|
; GRAPH-NEXT: [AANoUndef] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-undef-or-poison
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
|
; GRAPH-NEXT: [AAValueSimplify] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state simplified
|
||||||
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAAlign] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state align<16-16>
|
; GRAPH-NEXT: [AAAlign] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state align<16-16>
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANonNull] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
|
; GRAPH-NEXT: [AANonNull] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state nonnull
|
||||||
|
@ -226,20 +224,14 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
|
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_arg: [@0]} with state nonnull
|
||||||
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
||||||
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
||||||
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' ret i32* %.0' at position {flt: [@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' ret i32* %.0' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state assumed-live
|
|
||||||
; GRAPH-EMPTY:
|
|
||||||
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' br label %8' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANoAlias] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state may-alias
|
; GRAPH-NEXT: [AAIsDead] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state assumed-live
|
||||||
; GRAPH-EMPTY:
|
|
||||||
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
|
||||||
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
|
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAWillReturn] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-noreturn
|
; GRAPH-NEXT: [AAWillReturn] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state may-noreturn
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
|
@ -251,13 +243,18 @@ define i32* @checkAndAdvance(i32* align 16 %0) {
|
||||||
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
|
; GRAPH-NEXT: [AANoFree] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state nofree
|
||||||
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
|
; GRAPH-NEXT: updates [AANoFree] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state nofree
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
|
; GRAPH-NEXT: [AAMemoryLocation] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs: [@-1]} with state memory:argument
|
||||||
|
; GRAPH-NEXT: updates [AAMemoryLocation] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn:checkAndAdvance [checkAndAdvance@-1]} with state memory:argument
|
||||||
|
; GRAPH-EMPTY:
|
||||||
|
; GRAPH-NEXT: [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
|
||||||
|
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
|
||||||
|
; GRAPH-EMPTY:
|
||||||
|
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state unknown-dereferenceable
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state nonnull
|
; GRAPH-NEXT: [AANonNull] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state nonnull
|
||||||
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
; GRAPH-NEXT: updates [AANonNull] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state nonnull
|
||||||
; GRAPH-EMPTY:
|
; GRAPH-EMPTY:
|
||||||
; GRAPH-NEXT: [AAAlign] for CtxI ' %6 = call i32* @checkAndAdvance(i32* %5)' at position {cs_ret: [@-1]} with state align<1-16>
|
; GRAPH-NEXT: [AADereferenceable] for CtxI ' %5 = getelementptr inbounds i32, i32* %0, i64 4' at position {flt: [@-1]} with state unknown-dereferenceable
|
||||||
; GRAPH-NEXT: updates [AAAlign] for CtxI ' %2 = load i32, i32* %0, align 4' at position {fn_ret:checkAndAdvance [checkAndAdvance@-1]} with state align<1-16>
|
|
||||||
|
|
||||||
; GRAPH-NOT: update
|
; GRAPH-NOT: update
|
||||||
|
|
||||||
|
|
|
@ -299,13 +299,15 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
||||||
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
|
; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
|
||||||
|
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
||||||
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
|
; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
|
||||||
|
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
|
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
|
||||||
|
|
|
@ -299,13 +299,15 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
||||||
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
|
; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
|
||||||
|
; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
|
||||||
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[PTR]], align 2
|
; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
|
||||||
|
; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
|
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
|
||||||
|
|
|
@ -57,21 +57,23 @@ define void @h2s_value_simplify_interaction(i1 %c, i8* %A) {
|
||||||
; IS________NPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction
|
; IS________NPM-LABEL: define {{[^@]+}}@h2s_value_simplify_interaction
|
||||||
; IS________NPM-SAME: (i1 [[C:%.*]], i8* nocapture nofree [[A:%.*]]) {
|
; IS________NPM-SAME: (i1 [[C:%.*]], i8* nocapture nofree [[A:%.*]]) {
|
||||||
; IS________NPM-NEXT: entry:
|
; IS________NPM-NEXT: entry:
|
||||||
; IS________NPM-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1
|
; IS________NPM-NEXT: [[M:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
||||||
; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
; IS________NPM-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; IS________NPM: t:
|
; IS________NPM: t:
|
||||||
; IS________NPM-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]]
|
; IS________NPM-NEXT: br i1 false, label [[DEAD:%.*]], label [[F2:%.*]]
|
||||||
; IS________NPM: f:
|
; IS________NPM: f:
|
||||||
; IS________NPM-NEXT: br label [[J:%.*]]
|
; IS________NPM-NEXT: br label [[J:%.*]]
|
||||||
; IS________NPM: f2:
|
; IS________NPM: f2:
|
||||||
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[TMP0]], align 1
|
; IS________NPM-NEXT: [[C1:%.*]] = bitcast i8* [[M]] to i32*
|
||||||
|
; IS________NPM-NEXT: [[C2:%.*]] = bitcast i32* [[C1]] to i8*
|
||||||
|
; IS________NPM-NEXT: [[L:%.*]] = load i8, i8* [[C2]], align 1
|
||||||
; IS________NPM-NEXT: call void @usei8(i8 [[L]])
|
; IS________NPM-NEXT: call void @usei8(i8 [[L]])
|
||||||
; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[TMP0]]) #[[ATTR6:[0-9]+]]
|
; IS________NPM-NEXT: call void @no_sync_func(i8* nocapture nofree noundef [[C2]]) #[[ATTR6:[0-9]+]]
|
||||||
; IS________NPM-NEXT: br label [[J]]
|
; IS________NPM-NEXT: br label [[J]]
|
||||||
; IS________NPM: dead:
|
; IS________NPM: dead:
|
||||||
; IS________NPM-NEXT: unreachable
|
; IS________NPM-NEXT: unreachable
|
||||||
; IS________NPM: j:
|
; IS________NPM: j:
|
||||||
; IS________NPM-NEXT: [[PHI:%.*]] = phi i8* [ [[TMP0]], [[F]] ], [ null, [[F2]] ]
|
; IS________NPM-NEXT: [[PHI:%.*]] = phi i8* [ [[M]], [[F]] ], [ null, [[F2]] ]
|
||||||
; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[PHI]]) #[[ATTR6]]
|
; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture nofree noundef [[PHI]]) #[[ATTR6]]
|
||||||
; IS________NPM-NEXT: ret void
|
; IS________NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -569,8 +571,9 @@ define i32 @irreducible_cfg(i32 %0) {
|
||||||
; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
|
; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
|
||||||
; IS________NPM-NEXT: br label [[TMP8]]
|
; IS________NPM-NEXT: br label [[TMP8]]
|
||||||
; IS________NPM: 15:
|
; IS________NPM: 15:
|
||||||
; IS________NPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
|
; IS________NPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
|
||||||
; IS________NPM-NEXT: ret i32 [[TMP16]]
|
; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
|
||||||
|
; IS________NPM-NEXT: ret i32 [[TMP17]]
|
||||||
;
|
;
|
||||||
%2 = call noalias i8* @malloc(i64 4)
|
%2 = call noalias i8* @malloc(i64 4)
|
||||||
%3 = bitcast i8* %2 to i32*
|
%3 = bitcast i8* %2 to i32*
|
||||||
|
|
|
@ -377,68 +377,37 @@ define void @test11() {
|
||||||
|
|
||||||
; TEST 12
|
; TEST 12
|
||||||
define i32 @irreducible_cfg(i32 %0) {
|
define i32 @irreducible_cfg(i32 %0) {
|
||||||
; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg
|
; CHECK-LABEL: define {{[^@]+}}@irreducible_cfg
|
||||||
; IS________OPM-SAME: (i32 [[TMP0:%.*]]) {
|
; CHECK-SAME: (i32 [[TMP0:%.*]]) {
|
||||||
; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4)
|
; CHECK-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4)
|
||||||
; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
|
||||||
; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4
|
; CHECK-NEXT: store i32 10, i32* [[TMP3]], align 4
|
||||||
; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
|
||||||
; IS________OPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
|
; CHECK-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
|
||||||
; IS________OPM: 5:
|
; CHECK: 5:
|
||||||
; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
|
; CHECK-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
|
||||||
; IS________OPM-NEXT: br label [[TMP13:%.*]]
|
; CHECK-NEXT: br label [[TMP13:%.*]]
|
||||||
; IS________OPM: 7:
|
; CHECK: 7:
|
||||||
; IS________OPM-NEXT: br label [[TMP8:%.*]]
|
; CHECK-NEXT: br label [[TMP8:%.*]]
|
||||||
; IS________OPM: 8:
|
; CHECK: 8:
|
||||||
; IS________OPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
|
; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
|
||||||
; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
|
; CHECK-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
|
||||||
; IS________OPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
|
; CHECK-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
|
||||||
; IS________OPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4
|
; CHECK-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4
|
||||||
; IS________OPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
|
; CHECK-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
|
||||||
; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
|
; CHECK-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
|
||||||
; IS________OPM: 12:
|
; CHECK: 12:
|
||||||
; IS________OPM-NEXT: br label [[TMP13]]
|
; CHECK-NEXT: br label [[TMP13]]
|
||||||
; IS________OPM: 13:
|
; CHECK: 13:
|
||||||
; IS________OPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
|
; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
|
||||||
; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
|
; CHECK-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
|
||||||
; IS________OPM-NEXT: br label [[TMP8]]
|
; CHECK-NEXT: br label [[TMP8]]
|
||||||
; IS________OPM: 15:
|
; CHECK: 15:
|
||||||
; IS________OPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
|
; CHECK-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
|
||||||
; IS________OPM-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8*
|
; CHECK-NEXT: [[TMP17:%.*]] = bitcast i32* [[TMP3]] to i8*
|
||||||
; IS________OPM-NEXT: call void @free(i8* nocapture noundef [[TMP17]])
|
; CHECK-NEXT: call void @free(i8* nocapture noundef [[TMP17]])
|
||||||
; IS________OPM-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4
|
; CHECK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP3]], align 4
|
||||||
; IS________OPM-NEXT: ret i32 [[TMP18]]
|
; CHECK-NEXT: ret i32 [[TMP18]]
|
||||||
;
|
|
||||||
; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg
|
|
||||||
; IS________NPM-SAME: (i32 [[TMP0:%.*]]) {
|
|
||||||
; IS________NPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 noundef 4)
|
|
||||||
; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
|
|
||||||
; IS________NPM-NEXT: store i32 10, i32* [[TMP3]], align 4
|
|
||||||
; IS________NPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
|
|
||||||
; IS________NPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label [[TMP7:%.*]]
|
|
||||||
; IS________NPM: 5:
|
|
||||||
; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
|
|
||||||
; IS________NPM-NEXT: br label [[TMP13:%.*]]
|
|
||||||
; IS________NPM: 7:
|
|
||||||
; IS________NPM-NEXT: br label [[TMP8:%.*]]
|
|
||||||
; IS________NPM: 8:
|
|
||||||
; IS________NPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]], [[TMP13]] ], [ 1, [[TMP7]] ]
|
|
||||||
; IS________NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
|
|
||||||
; IS________NPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
|
|
||||||
; IS________NPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4
|
|
||||||
; IS________NPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
|
|
||||||
; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label [[TMP15:%.*]]
|
|
||||||
; IS________NPM: 12:
|
|
||||||
; IS________NPM-NEXT: br label [[TMP13]]
|
|
||||||
; IS________NPM: 13:
|
|
||||||
; IS________NPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [ [[DOT0]], [[TMP12]] ]
|
|
||||||
; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
|
|
||||||
; IS________NPM-NEXT: br label [[TMP8]]
|
|
||||||
; IS________NPM: 15:
|
|
||||||
; IS________NPM-NEXT: [[TMP16:%.*]] = load i32, i32* [[TMP3]], align 4
|
|
||||||
; IS________NPM-NEXT: call void @free(i8* nocapture noundef [[TMP2]])
|
|
||||||
; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
|
|
||||||
; IS________NPM-NEXT: ret i32 [[TMP17]]
|
|
||||||
;
|
;
|
||||||
%2 = call noalias i8* @malloc(i64 4)
|
%2 = call noalias i8* @malloc(i64 4)
|
||||||
%3 = bitcast i8* %2 to i32*
|
%3 = bitcast i8* %2 to i32*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
; Deep Wrapper enabled
|
; Deep Wrapper enabled
|
||||||
|
|
||||||
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM,CHECK_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_TUNIT_NPM_ENABLED,IS__TUNIT_____ENABLED,IS________OPM_ENABLED,IS__TUNIT_OPM_ENABLED
|
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM,CHECK_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_TUNIT_NPM_ENABLED,IS__TUNIT_____ENABLED,IS________OPM_ENABLED,IS__TUNIT_OPM_ENABLED
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=13 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM,CHECK_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,IS__TUNIT_____ENABLED,IS________NPM_ENABLED,IS__TUNIT_NPM_ENABLED
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM,CHECK_ENABLED,NOT_CGSCC_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,IS__TUNIT_____ENABLED,IS________NPM_ENABLED,IS__TUNIT_NPM_ENABLED
|
||||||
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,IS__CGSCC_____ENABLED,IS________OPM_ENABLED,IS__CGSCC_OPM_ENABLED
|
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_NPM_ENABLED,IS__CGSCC_____ENABLED,IS________OPM_ENABLED,IS__CGSCC_OPM_ENABLED
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_OPM_ENABLED,IS__CGSCC_____ENABLED,IS________NPM_ENABLED,IS__CGSCC_NPM_ENABLED
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -attributor-allow-deep-wrappers -disable-inlining -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM,CHECK_ENABLED,NOT_TUNIT_NPM_ENABLED,NOT_TUNIT_OPM_ENABLED,NOT_CGSCC_OPM_ENABLED,IS__CGSCC_____ENABLED,IS________NPM_ENABLED,IS__CGSCC_NPM_ENABLED
|
||||||
|
|
||||||
|
|
|
@ -2310,7 +2310,7 @@ define void @call_via_pointer_with_dead_args(i32* %a, i32* %b, void (i32*, i32*,
|
||||||
; FIXME: We have to prevent the propagation of %fp in the new pm CGSCC pass until the CallGraphUpdater can handle the new call edge.
|
; FIXME: We have to prevent the propagation of %fp in the new pm CGSCC pass until the CallGraphUpdater can handle the new call edge.
|
||||||
define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
|
define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
|
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
|
||||||
; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) {
|
; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) {
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @called_via_pointer(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
|
; NOT_CGSCC_NPM-NEXT: call void @called_via_pointer(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
|
||||||
; NOT_CGSCC_NPM-NEXT: ret void
|
; NOT_CGSCC_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -2324,7 +2324,7 @@ define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a, i32* %
|
||||||
}
|
}
|
||||||
define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
|
define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a, i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
|
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
|
||||||
; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]]) {
|
; NOT_CGSCC_NPM-SAME: (i32* [[A:%.*]], i32* noundef nonnull align 128 dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef nonnull [[FP:%.*]]) {
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @called_via_pointer_internal_2(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
|
; NOT_CGSCC_NPM-NEXT: call void @called_via_pointer_internal_2(i32* [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
|
||||||
; NOT_CGSCC_NPM-NEXT: ret void
|
; NOT_CGSCC_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -2345,8 +2345,8 @@ define void @call_via_pointer_with_dead_args_caller(i32* %a, i32* %b) {
|
||||||
; NOT_CGSCC_NPM-NEXT: [[PTR4:%.*]] = alloca i32, align 128
|
; NOT_CGSCC_NPM-NEXT: [[PTR4:%.*]] = alloca i32, align 128
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer)
|
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer)
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer_internal_1)
|
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer_internal_1)
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR3]])
|
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer)
|
||||||
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR4]])
|
; NOT_CGSCC_NPM-NEXT: call void @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* noundef nonnull align 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree noundef @called_via_pointer_internal_2)
|
||||||
; NOT_CGSCC_NPM-NEXT: ret void
|
; NOT_CGSCC_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
|
||||||
|
@ -2434,7 +2434,7 @@ define internal void @dead_with_blockaddress_users(i32* nocapture %pc) nounwind
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_with_blockaddress_users
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_with_blockaddress_users
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR14:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readonly align 536870912 dereferenceable(4294967295) [[PC:%.*]]) #[[ATTR14:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: br label [[INDIRECTGOTO:%.*]]
|
; IS__CGSCC____-NEXT: br label [[INDIRECTGOTO:%.*]]
|
||||||
; IS__CGSCC____: lab0:
|
; IS__CGSCC____: lab0:
|
||||||
|
|
|
@ -7,87 +7,47 @@
|
||||||
; FIXME: DOT should be replaced with 3
|
; FIXME: DOT should be replaced with 3
|
||||||
|
|
||||||
define i32 @test-ashr(i32 %c) {
|
define i32 @test-ashr(i32 %c) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-ashr
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test-ashr
|
||||||
; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: chk65:
|
; IS__TUNIT____-NEXT: chk65:
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
||||||
; IS__TUNIT_OPM: chk0:
|
; IS__TUNIT____: chk0:
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
||||||
; IS__TUNIT_OPM: bb_if:
|
; IS__TUNIT____: bb_if:
|
||||||
; IS__TUNIT_OPM-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
; IS__TUNIT____-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
||||||
; IS__TUNIT_OPM: bb_then:
|
; IS__TUNIT____: bb_then:
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
|
; IS__TUNIT____-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
|
||||||
; IS__TUNIT_OPM-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
|
; IS__TUNIT____-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT_OPM: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT_OPM-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32 [[RETVAL]]
|
; IS__TUNIT____-NEXT: ret i32 [[RETVAL]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-ashr
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test-ashr
|
||||||
; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: chk65:
|
; IS__CGSCC____-NEXT: chk65:
|
||||||
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
||||||
; IS__TUNIT_NPM: chk0:
|
; IS__CGSCC____: chk0:
|
||||||
; IS__TUNIT_NPM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
; IS__CGSCC____-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
||||||
; IS__TUNIT_NPM: bb_if:
|
; IS__CGSCC____: bb_if:
|
||||||
; IS__TUNIT_NPM-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
; IS__CGSCC____-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
||||||
; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
||||||
; IS__TUNIT_NPM: bb_then:
|
; IS__CGSCC____: bb_then:
|
||||||
; IS__TUNIT_NPM-NEXT: [[DOT:%.*]] = select i1 true, i32 3, i32 2
|
; IS__CGSCC____-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
|
||||||
; IS__TUNIT_NPM: return:
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT_NPM-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
; IS__CGSCC____: return:
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32 [[RETVAL]]
|
; IS__CGSCC____-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
||||||
;
|
; IS__CGSCC____-NEXT: ret i32 [[RETVAL]]
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test-ashr
|
|
||||||
; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: chk65:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
|
||||||
; IS__CGSCC_OPM: chk0:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
|
||||||
; IS__CGSCC_OPM: bb_if:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
|
||||||
; IS__CGSCC_OPM: bb_then:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[RETURN]]
|
|
||||||
; IS__CGSCC_OPM: return:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[RETVAL]]
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test-ashr
|
|
||||||
; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: chk65:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
|
|
||||||
; IS__CGSCC_NPM: chk0:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
|
|
||||||
; IS__CGSCC_NPM: bb_if:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
|
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
|
|
||||||
; IS__CGSCC_NPM: bb_then:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[DOT:%.*]] = select i1 true, i32 3, i32 2
|
|
||||||
; IS__CGSCC_NPM-NEXT: br label [[RETURN]]
|
|
||||||
; IS__CGSCC_NPM: return:
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 [[RETVAL]]
|
|
||||||
;
|
;
|
||||||
chk65:
|
chk65:
|
||||||
%cmp = icmp sgt i32 %c, 65
|
%cmp = icmp sgt i32 %c, 65
|
||||||
|
@ -112,7 +72,7 @@ return:
|
||||||
ret i32 %retval
|
ret i32 %retval
|
||||||
}
|
}
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
@ -631,7 +631,7 @@ define i8 @readnone_caller(i1 %c) {
|
||||||
define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
|
define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
|
||||||
; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
|
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
|
||||||
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
|
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
|
||||||
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; IS__TUNIT____: t:
|
; IS__TUNIT____: t:
|
||||||
|
@ -644,7 +644,7 @@ define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
|
||||||
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
|
; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]]) #[[ATTR8]] {
|
||||||
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
|
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
|
||||||
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; IS__CGSCC____: t:
|
; IS__CGSCC____: t:
|
||||||
|
|
|
@ -429,11 +429,13 @@ define void @test12_4(){
|
||||||
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() {
|
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test12_4() {
|
||||||
; NOT_TUNIT_OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
; NOT_TUNIT_OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
||||||
; NOT_TUNIT_OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
; NOT_TUNIT_OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
||||||
|
; NOT_TUNIT_OPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
|
||||||
; NOT_TUNIT_OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
|
; NOT_TUNIT_OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
|
||||||
|
; NOT_TUNIT_OPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
|
||||||
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]])
|
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* noalias nocapture [[A]], i8* noalias nocapture [[B]])
|
||||||
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A]])
|
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_0]])
|
||||||
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
|
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[A_1]])
|
||||||
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A]], i8* nocapture [[B]])
|
; NOT_TUNIT_OPM-NEXT: tail call void @two_args(i8* nocapture [[A_0]], i8* nocapture [[B_0]])
|
||||||
; NOT_TUNIT_OPM-NEXT: ret void
|
; NOT_TUNIT_OPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
%A = tail call noalias i8* @malloc(i64 4)
|
%A = tail call noalias i8* @malloc(i64 4)
|
||||||
|
@ -465,17 +467,12 @@ define void @use_i8_internal(i8* %a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test13_use_noalias(){
|
define void @test13_use_noalias(){
|
||||||
; IS________OPM-LABEL: define {{[^@]+}}@test13_use_noalias() {
|
; CHECK-LABEL: define {{[^@]+}}@test13_use_noalias() {
|
||||||
; IS________OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
||||||
; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
|
; CHECK-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
|
||||||
; IS________OPM-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8*
|
; CHECK-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8*
|
||||||
; IS________OPM-NEXT: call void @use_i8_internal(i8* noalias nocapture [[C2]])
|
; CHECK-NEXT: call void @use_i8_internal(i8* noalias nocapture [[C2]])
|
||||||
; IS________OPM-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
|
||||||
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_noalias() {
|
|
||||||
; NOT_TUNIT_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
|
||||||
; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* noalias nocapture [[M1]])
|
|
||||||
; NOT_TUNIT_OPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
|
||||||
; IS__CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
|
; IS__CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
|
||||||
|
@ -491,20 +488,14 @@ define void @test13_use_noalias(){
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test13_use_alias(){
|
define void @test13_use_alias(){
|
||||||
; IS________OPM-LABEL: define {{[^@]+}}@test13_use_alias() {
|
; CHECK-LABEL: define {{[^@]+}}@test13_use_alias() {
|
||||||
; IS________OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
; CHECK-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
||||||
; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
|
; CHECK-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
|
||||||
; IS________OPM-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
|
; CHECK-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
|
||||||
; IS________OPM-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
|
; CHECK-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
|
||||||
; IS________OPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2A]])
|
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[C2A]])
|
||||||
; IS________OPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2B]])
|
; CHECK-NEXT: call void @use_i8_internal(i8* nocapture [[C2B]])
|
||||||
; IS________OPM-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
|
||||||
; NOT_TUNIT_OPM-LABEL: define {{[^@]+}}@test13_use_alias() {
|
|
||||||
; NOT_TUNIT_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 noundef 4)
|
|
||||||
; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* nocapture [[M1]])
|
|
||||||
; NOT_TUNIT_OPM-NEXT: call void @use_i8_internal(i8* nocapture [[M1]])
|
|
||||||
; NOT_TUNIT_OPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
%m1 = tail call noalias i8* @malloc(i64 4)
|
%m1 = tail call noalias i8* @malloc(i64 4)
|
||||||
%c1 = bitcast i8* %m1 to i16*
|
%c1 = bitcast i8* %m1 to i16*
|
||||||
|
|
|
@ -54,7 +54,7 @@ define void @c3(i32* %q) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@c3
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@c3
|
||||||
; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR19:[0-9]+]]
|
; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]]) #[[ATTR17:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @c2(i32* %q)
|
call void @c2(i32* %q)
|
||||||
|
@ -221,14 +221,14 @@ define i1 @c7(i32* %q, i32 %bitno) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@c7
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@c7
|
||||||
; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {
|
; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {
|
||||||
; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR17:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR15:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
|
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
|
||||||
; IS__TUNIT____-NEXT: ret i1 [[VAL]]
|
; IS__TUNIT____-NEXT: ret i1 [[VAL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@c7
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@c7
|
||||||
; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]]) #[[ATTR2]] {
|
||||||
; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR20:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]]) #[[ATTR18:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
|
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
|
||||||
; IS__CGSCC____-NEXT: ret i1 [[VAL]]
|
; IS__CGSCC____-NEXT: ret i1 [[VAL]]
|
||||||
;
|
;
|
||||||
|
@ -245,23 +245,27 @@ define i32 @nc1(i32* %q, i32* %p, i1 %b) {
|
||||||
; IS__TUNIT____-NEXT: e:
|
; IS__TUNIT____-NEXT: e:
|
||||||
; IS__TUNIT____-NEXT: br label [[L:%.*]]
|
; IS__TUNIT____-NEXT: br label [[L:%.*]]
|
||||||
; IS__TUNIT____: l:
|
; IS__TUNIT____: l:
|
||||||
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
|
; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
|
||||||
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
|
; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
|
||||||
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
|
||||||
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
|
; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
|
||||||
; IS__TUNIT____-NEXT: store i32 0, i32* [[P]], align 4
|
; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4
|
||||||
; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
|
; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[VAL]]
|
; IS__TUNIT____-NEXT: ret i32 [[VAL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1
|
||||||
; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree align 4 [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]]) #[[ATTR5:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: e:
|
; IS__CGSCC____-NEXT: e:
|
||||||
; IS__CGSCC____-NEXT: br label [[L:%.*]]
|
; IS__CGSCC____-NEXT: br label [[L:%.*]]
|
||||||
; IS__CGSCC____: l:
|
; IS__CGSCC____: l:
|
||||||
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E:%.*]] ]
|
; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
|
||||||
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[P]], i32* [[Y]]
|
; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
|
||||||
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
|
||||||
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
|
; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
|
||||||
; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4
|
; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4
|
||||||
; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
|
; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[VAL]]
|
; IS__CGSCC____-NEXT: ret i32 [[VAL]]
|
||||||
;
|
;
|
||||||
|
@ -331,8 +335,8 @@ define void @nc2(i32* %p, i32* %q) {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree align 4 [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]]) #[[ATTR5]] {
|
||||||
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree align 4 [[P]], i1 noundef false) #[[ATTR16:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 noundef false) #[[ATTR14:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
|
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
|
||||||
|
@ -357,13 +361,13 @@ define void @nc4(i8* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nounwind
|
; IS__TUNIT____: Function Attrs: argmemonly nounwind
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@nc4
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@nc4
|
||||||
; IS__TUNIT____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR18:[0-9]+]]
|
; IS__TUNIT____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR16:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc4
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@nc4
|
||||||
; IS__CGSCC____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* [[P:%.*]]) #[[ATTR6:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR21:[0-9]+]]
|
; IS__CGSCC____-NEXT: call void @external(i8* readonly [[P]]) #[[ATTR19:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @external(i8* %p)
|
call void @external(i8* %p)
|
||||||
|
@ -607,19 +611,19 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @nocaptureLaunder(i8* %p) {
|
define void @nocaptureLaunder(i8* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureLaunder
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureLaunder
|
||||||
; IS__TUNIT____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR10:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR5]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR19:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1
|
; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureLaunder
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureLaunder
|
||||||
; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR10:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* nocapture nofree [[P:%.*]]) #[[ATTR10:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR22:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1
|
; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -634,14 +638,14 @@ define void @captureLaunder(i8* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureLaunder
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureLaunder
|
||||||
; IS__TUNIT____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR5]] {
|
; IS__TUNIT____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR5]] {
|
||||||
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR19]]
|
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR17]]
|
||||||
; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g2, align 8
|
; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g2, align 8
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureLaunder
|
||||||
; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR11:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* nofree [[P:%.*]]) #[[ATTR10]] {
|
||||||
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR22]]
|
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* nofree [[P]]) #[[ATTR20]]
|
||||||
; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8
|
; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g2, align 8
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -651,19 +655,19 @@ define void @captureLaunder(i8* %p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @nocaptureStrip(i8* %p) {
|
define void @nocaptureStrip(i8* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureStrip
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureStrip
|
||||||
; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR11:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1
|
; IS__TUNIT____-NEXT: store i8 42, i8* [[B]], align 1
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureStrip
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureStrip
|
||||||
; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR12:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[P:%.*]]) #[[ATTR11:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20]]
|
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]]
|
||||||
; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1
|
; IS__CGSCC____-NEXT: store i8 42, i8* [[B]], align 1
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -678,14 +682,14 @@ define void @captureStrip(i8* %p) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureStrip
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureStrip
|
||||||
; IS__TUNIT____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20]]
|
; IS__TUNIT____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]]
|
||||||
; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g3, align 8
|
; IS__TUNIT____-NEXT: store i8* [[B]], i8** @g3, align 8
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureStrip
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureStrip
|
||||||
; IS__CGSCC____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR13:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i8* nofree writeonly [[P:%.*]]) #[[ATTR11]] {
|
||||||
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR20]]
|
; IS__CGSCC____-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias nofree readnone [[P]]) #[[ATTR18]]
|
||||||
; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g3, align 8
|
; IS__CGSCC____-NEXT: store i8* [[B]], i8** @g3, align 8
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -785,14 +789,14 @@ define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x
|
||||||
define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid {
|
define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
|
||||||
; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR12:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR10:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
|
||||||
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
|
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
|
||||||
; IS__TUNIT____-NEXT: ret i1 [[TMP2]]
|
; IS__TUNIT____-NEXT: ret i1 [[TMP2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
|
||||||
; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR14:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]]) #[[ATTR12:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
|
||||||
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
|
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
|
||||||
; IS__CGSCC____-NEXT: ret i1 [[TMP2]]
|
; IS__CGSCC____-NEXT: ret i1 [[TMP2]]
|
||||||
|
@ -822,7 +826,7 @@ define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly {
|
||||||
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
|
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]])
|
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]])
|
||||||
; CHECK-NEXT: ret i8* [[B]]
|
; CHECK-NEXT: ret i8* [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B)
|
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B)
|
||||||
|
@ -835,7 +839,7 @@ define i8* @test_returned2(i8* %A, i8* %B) {
|
||||||
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
|
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]]) #[[ATTR4]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]]
|
; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]], i8* readonly [[B]]) #[[ATTR4]]
|
||||||
; CHECK-NEXT: ret i8* [[B]]
|
; CHECK-NEXT: ret i8* [[P]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly
|
%p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly
|
||||||
|
@ -850,13 +854,13 @@ declare void @val_use(i8 %ptr) readonly nounwind willreturn
|
||||||
define void @ptr_uses(i8* %ptr, i8* %wptr) {
|
define void @ptr_uses(i8* %ptr, i8* %wptr) {
|
||||||
; IS__TUNIT____: Function Attrs: nounwind willreturn
|
; IS__TUNIT____: Function Attrs: nounwind willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_uses
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_uses
|
||||||
; IS__TUNIT____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR14:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR12:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: store i8 0, i8* [[WPTR]], align 1
|
; IS__TUNIT____-NEXT: store i8 0, i8* [[WPTR]], align 1
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nounwind willreturn
|
; IS__CGSCC____: Function Attrs: nounwind willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_uses
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_uses
|
||||||
; IS__CGSCC____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR16]] {
|
; IS__CGSCC____-SAME: (i8* [[PTR:%.*]], i8* nocapture nofree noundef nonnull writeonly dereferenceable(1) [[WPTR:%.*]]) #[[ATTR14]] {
|
||||||
; IS__CGSCC____-NEXT: store i8 0, i8* [[WPTR]], align 1
|
; IS__CGSCC____-NEXT: store i8 0, i8* [[WPTR]], align 1
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -880,17 +884,15 @@ declare i8* @llvm.strip.invariant.group.p0i8(i8*)
|
||||||
; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
|
; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
|
||||||
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree noreturn nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree noreturn nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR9]] = { argmemonly nofree nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR9]] = { argmemonly nofree nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR10]] = { inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR10]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR11]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT____: attributes #[[ATTR11:[0-9]+]] = { nounwind readonly willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR12]] = { nofree nosync nounwind null_pointer_is_valid readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR12]] = { nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR13:[0-9]+]] = { nounwind readonly willreturn }
|
; IS__TUNIT____: attributes #[[ATTR13:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR14]] = { nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR14:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn }
|
; IS__TUNIT____: attributes #[[ATTR15]] = { nofree nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
|
; IS__TUNIT____: attributes #[[ATTR16]] = { nounwind }
|
||||||
; IS__TUNIT____: attributes #[[ATTR17]] = { nofree nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR17]] = { willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR18]] = { nounwind }
|
; IS__TUNIT____: attributes #[[ATTR18]] = { readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR19]] = { willreturn }
|
|
||||||
; IS__TUNIT____: attributes #[[ATTR20]] = { readnone willreturn }
|
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
||||||
|
@ -902,17 +904,15 @@ declare i8* @llvm.strip.invariant.group.p0i8(i8*)
|
||||||
; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
|
; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind writeonly }
|
||||||
; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR8]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR9]] = { argmemonly nofree norecurse nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR10]] = { inaccessiblemem_or_argmemonly nofree nosync nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR10]] = { nofree nosync nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR11]] = { nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__CGSCC____: attributes #[[ATTR12]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
; IS__CGSCC____: attributes #[[ATTR12]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR13]] = { nofree nosync nounwind willreturn writeonly }
|
; IS__CGSCC____: attributes #[[ATTR13:[0-9]+]] = { nounwind readonly willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR14]] = { nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { nounwind readonly willreturn }
|
; IS__CGSCC____: attributes #[[ATTR15:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR16]] = { nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR16:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR17:[0-9]+]] = { inaccessiblememonly nofree nosync nounwind speculatable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR17]] = { nounwind willreturn writeonly }
|
||||||
; IS__CGSCC____: attributes #[[ATTR18:[0-9]+]] = { nofree nosync nounwind readnone speculatable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR18]] = { readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind willreturn writeonly }
|
; IS__CGSCC____: attributes #[[ATTR19]] = { nounwind }
|
||||||
; IS__CGSCC____: attributes #[[ATTR20]] = { readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR20]] = { willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR21]] = { nounwind }
|
|
||||||
; IS__CGSCC____: attributes #[[ATTR22]] = { willreturn }
|
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
;
|
;
|
||||||
|
@ -219,9 +219,9 @@ define float* @scc_A(i32* dereferenceable_or_null(4) %a) {
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16*
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16*
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double*
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double*
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32*
|
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32*
|
||||||
; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL2:%.*]] = call float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32*
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32*
|
||||||
; CHECK-NEXT: br label [[COND_END:%.*]]
|
; CHECK-NEXT: br label [[COND_END:%.*]]
|
||||||
; CHECK: cond.false:
|
; CHECK: cond.false:
|
||||||
|
@ -254,7 +254,6 @@ cond.end: ; preds = %cond.false, %cond.t
|
||||||
ret float* %4
|
ret float* %4
|
||||||
}
|
}
|
||||||
|
|
||||||
; FIXME: the call1 below to scc_B should return dereferenceable_or_null(8) (as the callee does). Something prevented that deduction and needs to be investigated.
|
|
||||||
define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
|
define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
|
||||||
; CHECK: Function Attrs: nofree nosync nounwind readnone
|
; CHECK: Function Attrs: nofree nosync nounwind readnone
|
||||||
; CHECK-LABEL: define {{[^@]+}}@scc_B
|
; CHECK-LABEL: define {{[^@]+}}@scc_B
|
||||||
|
@ -266,9 +265,9 @@ define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32*
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32*
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double*
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double*
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP1]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16*
|
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16*
|
||||||
; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL2:%.*]] = call i8* @scc_C(i16* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: br label [[COND_END:%.*]]
|
; CHECK-NEXT: br label [[COND_END:%.*]]
|
||||||
; CHECK: cond.false:
|
; CHECK: cond.false:
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8*
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8*
|
||||||
|
@ -313,7 +312,7 @@ define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
|
||||||
; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
|
||||||
; CHECK: cond.true:
|
; CHECK: cond.true:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double*
|
; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double*
|
||||||
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(4) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64* @scc_B(double* noalias nofree readnone dereferenceable_or_null(8) "no-capture-maybe-returned" [[TMP0]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8*
|
; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8*
|
||||||
; CHECK-NEXT: br label [[COND_END:%.*]]
|
; CHECK-NEXT: br label [[COND_END:%.*]]
|
||||||
; CHECK: cond.false:
|
; CHECK: cond.false:
|
||||||
|
@ -322,7 +321,7 @@ define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
|
||||||
; CHECK: cond.end:
|
; CHECK: cond.end:
|
||||||
; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ]
|
; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [ [[CALL2]], [[COND_FALSE]] ]
|
||||||
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32*
|
; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32*
|
||||||
; CHECK-NEXT: [[CALL3:%.*]] = call dereferenceable_or_null(4) float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
; CHECK-NEXT: [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP2]]) #[[ATTR2]]
|
||||||
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8*
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8*
|
||||||
; CHECK-NEXT: ret i8* [[TMP3]]
|
; CHECK-NEXT: ret i8* [[TMP3]]
|
||||||
;
|
;
|
||||||
|
@ -498,14 +497,14 @@ define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
|
||||||
; IS__TUNIT____-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
|
; IS__TUNIT____-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
||||||
; IS__TUNIT____-NEXT: ret i64* [[A]]
|
; IS__TUNIT____-NEXT: ret i64* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
|
; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
|
||||||
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
|
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR4]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
||||||
; IS__CGSCC____-NEXT: ret i64* [[A]]
|
; IS__CGSCC____-NEXT: ret i64* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i64* @not_captured_but_returned_0(i64* %a)
|
%call = call i64* @not_captured_but_returned_0(i64* %a)
|
||||||
|
@ -525,7 +524,7 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
|
||||||
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) #[[ATTR4]] {
|
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]]) #[[ATTR4]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
||||||
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
|
||||||
; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
|
; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -534,7 +533,7 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
|
||||||
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
|
; IS__CGSCC____-SAME: (i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR4]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree noundef nonnull writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR9]]
|
||||||
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[A]] to i64
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
|
||||||
; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
|
; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -702,7 +701,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* re
|
||||||
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] {
|
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8:[0-9]+]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
||||||
; CHECK-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
|
%call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
|
||||||
|
@ -716,7 +715,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r
|
||||||
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
||||||
; CHECK-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
|
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
|
||||||
|
@ -730,7 +729,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r
|
||||||
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32* nocapture readonly [[B]], i32* readonly [[R]]) #[[ATTR8]]
|
||||||
; CHECK-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
|
%call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
|
||||||
|
@ -743,7 +742,7 @@ define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r
|
||||||
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]]) #[[ATTR8]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]]
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32* readonly [[B]], i32* readonly [[R]]) #[[ATTR6]]
|
||||||
; CHECK-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)
|
%call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ define i8* @test2(i8* nonnull %p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test2A(i1 %c, i8* %ret) {
|
define i8* @test2A(i1 %c, i8* %ret) {
|
||||||
|
; ATTRIBUTOR: define nonnull i8* @test2A(i1 %c, i8* nofree nonnull readnone returned %ret)
|
||||||
; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
|
; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
|
||||||
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] {
|
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0:[0-9]+]] {
|
||||||
|
@ -68,6 +69,7 @@ B:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test2B(i1 %c, i8* %ret) {
|
define i8* @test2B(i1 %c, i8* %ret) {
|
||||||
|
; ATTRIBUTOR: define nonnull dereferenceable(4) i8* @test2B(i1 %c, i8* nofree nonnull readnone returned dereferenceable(4) %ret)
|
||||||
; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
|
; NOT_CGSCC_OPM: Function Attrs: inaccessiblememonly nofree nosync nounwind willreturn
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
|
||||||
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] {
|
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]]) #[[ATTR0]] {
|
||||||
|
@ -144,30 +146,22 @@ define i8* @test3(i1 %c) {
|
||||||
; nonnull if neither can ever return null. (In this case, they
|
; nonnull if neither can ever return null. (In this case, they
|
||||||
; just never return period.)
|
; just never return period.)
|
||||||
define i8* @test4_helper() {
|
define i8* @test4_helper() {
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
|
; CHECK-LABEL: define {{[^@]+}}@test4_helper
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
|
; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
; CHECK-NEXT: [[RET:%.*]] = call i8* @test4() #[[ATTR2]]
|
||||||
;
|
; CHECK-NEXT: unreachable
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR2:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
;
|
;
|
||||||
%ret = call i8* @test4()
|
%ret = call i8* @test4()
|
||||||
ret i8* %ret
|
ret i8* %ret
|
||||||
}
|
}
|
||||||
|
|
||||||
define i8* @test4() {
|
define i8* @test4() {
|
||||||
; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
|
; CHECK-LABEL: define {{[^@]+}}@test4
|
||||||
; NOT_CGSCC_NPM-SAME: () #[[ATTR2]] {
|
; CHECK-SAME: () #[[ATTR2]] {
|
||||||
; NOT_CGSCC_NPM-NEXT: unreachable
|
; CHECK-NEXT: [[RET:%.*]] = call i8* @test4_helper() #[[ATTR2]]
|
||||||
;
|
; CHECK-NEXT: unreachable
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR2]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
;
|
;
|
||||||
%ret = call i8* @test4_helper()
|
%ret = call i8* @test4_helper()
|
||||||
ret i8* %ret
|
ret i8* %ret
|
||||||
|
@ -233,7 +227,6 @@ define i8* @test5(i1 %c) {
|
||||||
|
|
||||||
; Local analysis, but going through a self recursive phi
|
; Local analysis, but going through a self recursive phi
|
||||||
define i8* @test6a() {
|
define i8* @test6a() {
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM: Function Attrs: noreturn
|
; NOT_CGSCC_OPM: Function Attrs: noreturn
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6a
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6a
|
||||||
; NOT_CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] {
|
; NOT_CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] {
|
||||||
|
@ -292,12 +285,14 @@ define i8* @test7(i8* %a) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
|
||||||
; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: ret i8* [[A]]
|
; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
|
||||||
|
; IS__TUNIT____-NEXT: ret i8* [[B]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
|
||||||
; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: ret i8* [[A]]
|
; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
|
||||||
|
; IS__CGSCC____-NEXT: ret i8* [[B]]
|
||||||
;
|
;
|
||||||
%b = getelementptr inbounds i8, i8* %a, i64 0
|
%b = getelementptr inbounds i8, i8* %a, i64 0
|
||||||
ret i8* %b
|
ret i8* %b
|
||||||
|
@ -427,7 +422,6 @@ define void @test13_helper() {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
define internal void @test13(i8* %a, i8* %b, i8* %c) {
|
define internal void @test13(i8* %a, i8* %b, i8* %c) {
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nounwind
|
; NOT_CGSCC_OPM: Function Attrs: nounwind
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13
|
||||||
; NOT_CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4]] {
|
; NOT_CGSCC_OPM-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]]) #[[ATTR4]] {
|
||||||
|
@ -641,7 +635,6 @@ if.else:
|
||||||
; fun1(nonnull %a)
|
; fun1(nonnull %a)
|
||||||
; We can say that %a is nonnull
|
; We can say that %a is nonnull
|
||||||
define void @f17(i8* %a, i8 %c) {
|
define void @f17(i8* %a, i8 %c) {
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
|
; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f17
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f17
|
||||||
; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
|
; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]]) #[[ATTR6]] {
|
||||||
|
@ -1113,7 +1106,6 @@ define internal void @called_by_weak(i32* %a) {
|
||||||
|
|
||||||
; Check we do not annotate the function interface of this weak function.
|
; Check we do not annotate the function interface of this weak function.
|
||||||
define weak_odr void @weak_caller(i32* nonnull %a) {
|
define weak_odr void @weak_caller(i32* nonnull %a) {
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@weak_caller
|
||||||
; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) {
|
; NOT_CGSCC_OPM-SAME: (i32* nonnull [[A:%.*]]) {
|
||||||
; NOT_CGSCC_OPM-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
|
; NOT_CGSCC_OPM-NEXT: call void @called_by_weak(i32* noalias nocapture nonnull readnone [[A]]) #[[ATTR4]]
|
||||||
|
@ -1164,7 +1156,6 @@ define internal void @naked(i32* dereferenceable(4) %a) naked {
|
||||||
}
|
}
|
||||||
; Avoid nonnull as we do not touch optnone
|
; Avoid nonnull as we do not touch optnone
|
||||||
define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
|
define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM: Function Attrs: noinline optnone
|
; NOT_CGSCC_OPM: Function Attrs: noinline optnone
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@optnone
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@optnone
|
||||||
; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] {
|
; NOT_CGSCC_OPM-SAME: (i32* dereferenceable(4) [[A:%.*]]) #[[ATTR10:[0-9]+]] {
|
||||||
|
@ -1639,7 +1630,6 @@ define void @nonnull_assume_neg(i8* %arg) {
|
||||||
; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
|
; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree nonnull readnone [[ARG]])
|
||||||
; ATTRIBUTOR-NEXT: ret void
|
; ATTRIBUTOR-NEXT: ret void
|
||||||
;
|
;
|
||||||
;
|
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
|
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_neg
|
||||||
; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
|
; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree readnone [[ARG:%.*]]) {
|
||||||
; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
|
; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
|
||||||
|
@ -1726,7 +1716,7 @@ attributes #1 = { nounwind willreturn}
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR3]] = { noreturn }
|
; IS__TUNIT____: attributes #[[ATTR3]] = { noreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR4]] = { nounwind }
|
; IS__TUNIT____: attributes #[[ATTR4]] = { nounwind }
|
||||||
; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
|
; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
|
||||||
|
@ -1742,7 +1732,7 @@ attributes #1 = { nounwind willreturn}
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { noreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind }
|
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nounwind }
|
||||||
|
@ -1759,7 +1749,7 @@ attributes #1 = { nounwind willreturn}
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { inaccessiblememonly nofree nosync nounwind willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { noreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind }
|
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nounwind }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
|
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind readonly }
|
||||||
|
|
|
@ -34,56 +34,32 @@ define i32 @self_rec() {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @indirect_rec() {
|
define i32 @indirect_rec() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@indirect_rec
|
; CHECK-LABEL: define {{[^@]+}}@indirect_rec
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: unreachable
|
; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec2() #[[ATTR2]]
|
||||||
;
|
; CHECK-NEXT: unreachable
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@indirect_rec
|
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
;
|
;
|
||||||
%a = call i32 @indirect_rec2()
|
%a = call i32 @indirect_rec2()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
}
|
}
|
||||||
define i32 @indirect_rec2() {
|
define i32 @indirect_rec2() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@indirect_rec2
|
; CHECK-LABEL: define {{[^@]+}}@indirect_rec2
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
; CHECK-SAME: () #[[ATTR2]] {
|
||||||
; IS__TUNIT____-NEXT: unreachable
|
; CHECK-NEXT: [[A:%.*]] = call i32 @indirect_rec() #[[ATTR2]]
|
||||||
;
|
; CHECK-NEXT: unreachable
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@indirect_rec2
|
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR2]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: unreachable
|
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: unreachable
|
|
||||||
;
|
;
|
||||||
%a = call i32 @indirect_rec()
|
%a = call i32 @indirect_rec()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @extern() {
|
define i32 @extern() {
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nosync readnone
|
; CHECK: Function Attrs: nosync readnone
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@extern
|
; CHECK-LABEL: define {{[^@]+}}@extern
|
||||||
; NOT_CGSCC_OPM-SAME: () #[[ATTR2:[0-9]+]] {
|
; CHECK-SAME: () #[[ATTR3:[0-9]+]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @k()
|
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
|
||||||
; NOT_CGSCC_OPM-NEXT: ret i32 [[A]]
|
; CHECK-NEXT: ret i32 [[A]]
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: nosync readnone
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@extern
|
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR3:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @k()
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
|
|
||||||
;
|
;
|
||||||
%a = call i32 @k()
|
%a = call i32 @k()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
|
@ -94,17 +70,11 @@ define i32 @extern() {
|
||||||
declare i32 @k() readnone
|
declare i32 @k() readnone
|
||||||
|
|
||||||
define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
|
define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
|
||||||
; NOT_CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
; CHECK: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@intrinsic
|
; CHECK-LABEL: define {{[^@]+}}@intrinsic
|
||||||
; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR4:[0-9]+]] {
|
; CHECK-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR5:[0-9]+]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) #[[ATTR10:[0-9]+]]
|
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) #[[ATTR11:[0-9]+]]
|
||||||
; NOT_CGSCC_OPM-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@intrinsic
|
|
||||||
; IS__CGSCC_OPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly [[SRC]], i32 [[LEN]], i1 noundef false) #[[ATTR11:[0-9]+]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
|
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
|
||||||
ret void
|
ret void
|
||||||
|
@ -117,21 +87,15 @@ declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
|
||||||
define internal i32 @called_by_norecurse() {
|
define internal i32 @called_by_norecurse() {
|
||||||
; IS__TUNIT____: Function Attrs: nosync readnone
|
; IS__TUNIT____: Function Attrs: nosync readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_norecurse
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_norecurse
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR2]] {
|
; IS__TUNIT____-SAME: () #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @k()
|
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @k()
|
||||||
; IS__TUNIT____-NEXT: ret i32 undef
|
; IS__TUNIT____-NEXT: ret i32 undef
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: norecurse nosync readnone
|
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_norecurse
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR7:[0-9]+]] {
|
; IS__CGSCC____-SAME: () #[[ATTR7:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @k()
|
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k()
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 undef
|
; IS__CGSCC____-NEXT: ret i32 undef
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@called_by_norecurse
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR6:[0-9]+]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = call i32 @k()
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 undef
|
|
||||||
;
|
;
|
||||||
%a = call i32 @k()
|
%a = call i32 @k()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
|
@ -139,38 +103,26 @@ define internal i32 @called_by_norecurse() {
|
||||||
define void @m() norecurse {
|
define void @m() norecurse {
|
||||||
; IS__TUNIT____: Function Attrs: norecurse nosync readnone
|
; IS__TUNIT____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@m
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@m
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR6:[0-9]+]] {
|
; IS__TUNIT____-SAME: () #[[ATTR7:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse() #[[ATTR3]]
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: norecurse nosync readnone
|
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@m
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@m
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR7]] {
|
; IS__CGSCC____-SAME: () #[[ATTR7]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
|
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@m
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR6]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
%a = call i32 @called_by_norecurse()
|
%a = call i32 @called_by_norecurse()
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i32 @called_by_norecurse_indirectly() {
|
define internal i32 @called_by_norecurse_indirectly() {
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nosync readnone
|
; CHECK: Function Attrs: nosync readnone
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
|
; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
|
||||||
; NOT_CGSCC_OPM-SAME: () #[[ATTR2]] {
|
; CHECK-SAME: () #[[ATTR3]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @k()
|
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
|
||||||
; NOT_CGSCC_OPM-NEXT: ret i32 [[A]]
|
; CHECK-NEXT: ret i32 [[A]]
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: nosync readnone
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
|
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR3]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @k()
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
|
|
||||||
;
|
;
|
||||||
%a = call i32 @k()
|
%a = call i32 @k()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
|
@ -178,21 +130,15 @@ define internal i32 @called_by_norecurse_indirectly() {
|
||||||
define internal i32 @o() {
|
define internal i32 @o() {
|
||||||
; IS__TUNIT____: Function Attrs: nosync readnone
|
; IS__TUNIT____: Function Attrs: nosync readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@o
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@o
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR2]] {
|
; IS__TUNIT____-SAME: () #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly() #[[ATTR3]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: norecurse nosync readnone
|
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@o
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@o
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR7]] {
|
; IS__CGSCC____-SAME: () #[[ATTR7]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
|
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
|
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@o
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR6]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 [[A]]
|
|
||||||
;
|
;
|
||||||
%a = call i32 @called_by_norecurse_indirectly()
|
%a = call i32 @called_by_norecurse_indirectly()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
|
@ -200,56 +146,35 @@ define internal i32 @o() {
|
||||||
define i32 @p() norecurse {
|
define i32 @p() norecurse {
|
||||||
; IS__TUNIT____: Function Attrs: norecurse nosync readnone
|
; IS__TUNIT____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@p
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@p
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR6]] {
|
; IS__TUNIT____-SAME: () #[[ATTR7]] {
|
||||||
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @o() #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @o() #[[ATTR3]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: norecurse nosync readnone
|
; IS__CGSCC____: Function Attrs: norecurse nosync readnone
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@p
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@p
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR7]] {
|
; IS__CGSCC____-SAME: () #[[ATTR7]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = call i32 @o()
|
; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @o()
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
|
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
||||||
;
|
|
||||||
; IS__CGSCC_NPM: Function Attrs: norecurse nosync readnone
|
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@p
|
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR6]] {
|
|
||||||
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = call i32 @o()
|
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 [[A]]
|
|
||||||
;
|
;
|
||||||
%a = call i32 @o()
|
%a = call i32 @o()
|
||||||
ret i32 %a
|
ret i32 %a
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @f(i32 %x) {
|
define void @f(i32 %x) {
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
|
; CHECK: Function Attrs: nofree nosync nounwind readnone
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@f
|
; CHECK-LABEL: define {{[^@]+}}@f
|
||||||
; NOT_CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR7:[0-9]+]] {
|
; CHECK-SAME: (i32 [[X:%.*]]) #[[ATTR8:[0-9]+]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; NOT_CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
||||||
; NOT_CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
||||||
; NOT_CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
||||||
; NOT_CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||||
; NOT_CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; NOT_CGSCC_OPM: if.then:
|
; CHECK: if.then:
|
||||||
; NOT_CGSCC_OPM-NEXT: call void @g() #[[ATTR8:[0-9]+]]
|
; CHECK-NEXT: call void @g() #[[ATTR9:[0-9]+]]
|
||||||
; NOT_CGSCC_OPM-NEXT: br label [[IF_END]]
|
; CHECK-NEXT: br label [[IF_END]]
|
||||||
; NOT_CGSCC_OPM: if.end:
|
; CHECK: if.end:
|
||||||
; NOT_CGSCC_OPM-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
|
|
||||||
; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) #[[ATTR8:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
|
||||||
; IS__CGSCC_OPM: if.then:
|
|
||||||
; IS__CGSCC_OPM-NEXT: call void @g() #[[ATTR9:[0-9]+]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: br label [[IF_END]]
|
|
||||||
; IS__CGSCC_OPM: if.end:
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%x.addr = alloca i32, align 4
|
%x.addr = alloca i32, align 4
|
||||||
|
@ -267,19 +192,12 @@ if.end:
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @g() norecurse {
|
define void @g() norecurse {
|
||||||
; NOT_CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
|
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@g
|
; CHECK-LABEL: define {{[^@]+}}@g
|
||||||
; NOT_CGSCC_OPM-SAME: () #[[ATTR8]] {
|
; CHECK-SAME: () #[[ATTR9]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; NOT_CGSCC_OPM-NEXT: call void @f(i32 noundef 0) #[[ATTR7]]
|
; CHECK-NEXT: call void @f(i32 noundef 0) #[[ATTR8]]
|
||||||
; NOT_CGSCC_OPM-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
|
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR9]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: entry:
|
|
||||||
; IS__CGSCC_OPM-NEXT: call void @f(i32 noundef 0) #[[ATTR8]]
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret void
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
call void @f(i32 0)
|
call void @f(i32 0)
|
||||||
|
@ -305,17 +223,11 @@ define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{
|
define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{
|
||||||
; NOT_CGSCC_OPM: Function Attrs: null_pointer_is_valid
|
; CHECK: Function Attrs: null_pointer_is_valid
|
||||||
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@eval_func2
|
; CHECK-LABEL: define {{[^@]+}}@eval_func2
|
||||||
; NOT_CGSCC_OPM-SAME: (i32 (i32)* nocapture nofree noundef [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr #[[ATTR9:[0-9]+]] {
|
; CHECK-SAME: (i32 (i32)* nocapture nofree noundef [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr #[[ATTR10:[0-9]+]] {
|
||||||
; NOT_CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
|
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
|
||||||
; NOT_CGSCC_OPM-NEXT: ret i32 [[TMP3]]
|
; CHECK-NEXT: ret i32 [[TMP3]]
|
||||||
;
|
|
||||||
; IS__CGSCC_OPM: Function Attrs: null_pointer_is_valid
|
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@eval_func2
|
|
||||||
; IS__CGSCC_OPM-SAME: (i32 (i32)* nocapture nofree noundef [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr #[[ATTR10:[0-9]+]] {
|
|
||||||
; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
|
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[TMP3]]
|
|
||||||
;
|
;
|
||||||
%3 = tail call i32 %0(i32 %1) #2
|
%3 = tail call i32 %0(i32 %1) #2
|
||||||
ret i32 %3
|
ret i32 %3
|
||||||
|
@ -347,38 +259,27 @@ Dead:
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noreturn nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR1]] = { nofree noreturn nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2]] = { nosync readnone }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR3:[0-9]+]] = { readnone }
|
; IS__TUNIT____: attributes #[[ATTR3]] = { nosync readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR4:[0-9]+]] = { readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR5:[0-9]+]] = { argmemonly nofree nounwind willreturn }
|
; IS__TUNIT____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR6]] = { norecurse nosync readnone }
|
; IS__TUNIT____: attributes #[[ATTR6:[0-9]+]] = { argmemonly nofree nounwind willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
|
; IS__TUNIT____: attributes #[[ATTR7]] = { norecurse nosync readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone }
|
; IS__TUNIT____: attributes #[[ATTR8]] = { nofree nosync nounwind readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR9]] = { null_pointer_is_valid }
|
; IS__TUNIT____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR10]] = { willreturn }
|
; IS__TUNIT____: attributes #[[ATTR10]] = { null_pointer_is_valid }
|
||||||
|
; IS__TUNIT____: attributes #[[ATTR11]] = { willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noreturn nosync nounwind readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR3]] = { nosync readnone }
|
; IS__CGSCC____: attributes #[[ATTR3]] = { nosync readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR4:[0-9]+]] = { readnone }
|
; IS__CGSCC____: attributes #[[ATTR4:[0-9]+]] = { readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR6:[0-9]+]] = { argmemonly nofree nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { argmemonly nofree nounwind willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { norecurse nosync readnone }
|
; IS__CGSCC____: attributes #[[ATTR7]] = { norecurse nosync readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR8]] = { nofree nosync nounwind readnone }
|
; IS__CGSCC____: attributes #[[ATTR8]] = { nofree nosync nounwind readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone }
|
; IS__CGSCC____: attributes #[[ATTR9]] = { nofree norecurse nosync nounwind readnone }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR10]] = { null_pointer_is_valid }
|
; IS__CGSCC____: attributes #[[ATTR10]] = { null_pointer_is_valid }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR11]] = { willreturn }
|
; IS__CGSCC____: attributes #[[ATTR11]] = { willreturn }
|
||||||
;.
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse noreturn nosync nounwind readnone willreturn }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR2]] = { nosync readnone }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR3:[0-9]+]] = { readnone }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind willreturn }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR5:[0-9]+]] = { argmemonly nofree nounwind willreturn }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { norecurse nosync readnone }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind readnone }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR9]] = { null_pointer_is_valid }
|
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR10]] = { willreturn }
|
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -87,7 +87,6 @@ define void @caller_with_unused_arg(i1 %c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal void @callee_with_dead_arg(i1 %create, ...) {
|
define internal void @callee_with_dead_arg(i1 %create, ...) {
|
||||||
;
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@callee_with_dead_arg
|
; CHECK-LABEL: define {{[^@]+}}@callee_with_dead_arg
|
||||||
; CHECK-SAME: (i1 [[CREATE:%.*]], ...) {
|
; CHECK-SAME: (i1 [[CREATE:%.*]], ...) {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
|
@ -114,7 +113,6 @@ if.then3: ; preds = %entry
|
||||||
; try to come up with a different scheme to verify the `noundef` is dropped if
|
; try to come up with a different scheme to verify the `noundef` is dropped if
|
||||||
; signature rewriting is not happening.
|
; signature rewriting is not happening.
|
||||||
define void @caller_with_noundef_arg() {
|
define void @caller_with_noundef_arg() {
|
||||||
;
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {
|
; CHECK-LABEL: define {{[^@]+}}@caller_with_noundef_arg() {
|
||||||
; CHECK-NEXT: call void (i1, ...) @callee_with_dead_arg(i1 undef)
|
; CHECK-NEXT: call void (i1, ...) @callee_with_dead_arg(i1 undef)
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=23 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -enable-new-pm=0 -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=23 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=24 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -enable-new-pm=0 -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -enable-new-pm=0 -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
;
|
;
|
||||||
|
@ -100,10 +100,10 @@ define i32 @potential_test2(i1 %c) {
|
||||||
define internal i32 @iszero3(i32 %c) {
|
define internal i32 @iszero3(i32 %c) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero3
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@iszero3
|
||||||
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 undef, 0
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[C]], 0
|
||||||
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 undef to i32
|
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 [[CMP]] to i32
|
||||||
; IS__CGSCC____-NEXT: ret i32 undef
|
; IS__CGSCC____-NEXT: ret i32 [[RET]]
|
||||||
;
|
;
|
||||||
%cmp = icmp eq i32 %c, 0
|
%cmp = icmp eq i32 %c, 0
|
||||||
%ret = zext i1 %cmp to i32
|
%ret = zext i1 %cmp to i32
|
||||||
|
@ -113,10 +113,10 @@ define internal i32 @iszero3(i32 %c) {
|
||||||
define internal i32 @less_than_two(i32 %c) {
|
define internal i32 @less_than_two(i32 %c) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_two
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@less_than_two
|
||||||
; IS__CGSCC____-SAME: (i32 [[C:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32 noundef [[C:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 undef, 2
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[C]], 2
|
||||||
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 true to i32
|
; IS__CGSCC____-NEXT: [[RET:%.*]] = zext i1 true to i32
|
||||||
; IS__CGSCC____-NEXT: ret i32 undef
|
; IS__CGSCC____-NEXT: ret i32 1
|
||||||
;
|
;
|
||||||
%cmp = icmp slt i32 %c, 2
|
%cmp = icmp slt i32 %c, 2
|
||||||
%ret = zext i1 %cmp to i32
|
%ret = zext i1 %cmp to i32
|
||||||
|
@ -568,15 +568,25 @@ f:
|
||||||
|
|
||||||
; FIXME: returned value can be simplified to 0
|
; FIXME: returned value can be simplified to 0
|
||||||
define i32 @potential_test11(i1 %c) {
|
define i32 @potential_test11(i1 %c) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test11
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@potential_test11
|
||||||
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
; IS__TUNIT_OPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
|
; IS__TUNIT_OPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]], !range [[RNG2]]
|
; IS__TUNIT_OPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]]
|
||||||
; IS__TUNIT____-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
|
; IS__TUNIT_OPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
|
||||||
; IS__TUNIT____-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
|
; IS__TUNIT_OPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[ACC2]]
|
; IS__TUNIT_OPM-NEXT: ret i32 [[ACC2]]
|
||||||
|
;
|
||||||
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@potential_test11
|
||||||
|
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[ZERO1:%.*]] = call i32 @optimize_undef_1(i1 [[C]]) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[ZERO2:%.*]] = call i32 @optimize_undef_2(i1 [[C]]) #[[ATTR0]], !range [[RNG3:![0-9]+]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[ZERO3:%.*]] = call i32 @optimize_undef_3(i1 [[C]]) #[[ATTR0]], !range [[RNG2]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[ACC1:%.*]] = add i32 [[ZERO1]], [[ZERO2]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: [[ACC2:%.*]] = add i32 [[ACC1]], [[ZERO3]]
|
||||||
|
; IS__TUNIT_NPM-NEXT: ret i32 [[ACC2]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test11
|
||||||
|
@ -623,7 +633,7 @@ define i32 @optimize_poison_1(i1 %c) {
|
||||||
; IS__TUNIT_NPM: t:
|
; IS__TUNIT_NPM: t:
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32 0
|
; IS__TUNIT_NPM-NEXT: ret i32 0
|
||||||
; IS__TUNIT_NPM: f:
|
; IS__TUNIT_NPM: f:
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32 undef
|
; IS__TUNIT_NPM-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@optimize_poison_1
|
||||||
|
@ -641,7 +651,7 @@ define i32 @optimize_poison_1(i1 %c) {
|
||||||
; IS__CGSCC_NPM: t:
|
; IS__CGSCC_NPM: t:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 0
|
; IS__CGSCC_NPM-NEXT: ret i32 0
|
||||||
; IS__CGSCC_NPM: f:
|
; IS__CGSCC_NPM: f:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32 undef
|
; IS__CGSCC_NPM-NEXT: ret i32 0
|
||||||
;
|
;
|
||||||
br i1 %c, label %t, label %f
|
br i1 %c, label %t, label %f
|
||||||
t:
|
t:
|
||||||
|
@ -667,7 +677,7 @@ define i32 @potential_test12(i1 %c) {
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@potential_test12
|
||||||
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call noundef i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]]
|
; IS__CGSCC_OPM-NEXT: [[ZERO:%.*]] = call i32 @optimize_poison_1(i1 [[C]]) #[[ATTR2]], !range [[RNG3]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]]
|
; IS__CGSCC_OPM-NEXT: ret i32 [[ZERO]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
@ -705,7 +715,7 @@ define i32 @potential_test13_caller1() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_caller1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@potential_test13_caller1
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2]]
|
; IS__TUNIT____-NEXT: [[RET:%.*]] = call i32 @potential_test13_callee(i32 noundef 0) #[[ATTR0]], !range [[RNG2:![0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[RET]]
|
; IS__TUNIT____-NEXT: ret i32 [[RET]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -43,7 +43,7 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree align 4 [[R0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[W0]]
|
; IS__TUNIT____-NEXT: ret i32* [[CALL3]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw
|
||||||
|
@ -53,7 +53,7 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[W0]]
|
; IS__CGSCC____-NEXT: ret i32* [[CALL3]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
|
%call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
|
||||||
|
@ -86,12 +86,12 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
|
||||||
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[N0]]
|
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw
|
||||||
; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[R0:%.*]] = alloca i32, align 4
|
; IS__CGSCC____-NEXT: [[R0:%.*]] = alloca i32, align 4
|
||||||
; IS__CGSCC____-NEXT: [[R1:%.*]] = alloca i32, align 4
|
; IS__CGSCC____-NEXT: [[R1:%.*]] = alloca i32, align 4
|
||||||
|
@ -111,8 +111,8 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
|
||||||
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32* nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[N0]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32* undef
|
; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%r0 = alloca i32, align 4
|
%r0 = alloca i32, align 4
|
||||||
|
@ -143,7 +143,7 @@ return: ; preds = %if.end, %if.then
|
||||||
define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
|
define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret1_rrw
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret1_rrw
|
||||||
; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
||||||
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||||
|
@ -166,12 +166,12 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
|
||||||
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* undef
|
; IS__TUNIT____-NEXT: ret i32* undef
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rrw
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rrw
|
||||||
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) [[R1:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
||||||
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||||
|
@ -194,7 +194,7 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
|
||||||
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[R1]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32* undef
|
; IS__CGSCC____-NEXT: ret i32* undef
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -293,12 +293,12 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
|
||||||
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[W0]]
|
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rw
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rw
|
||||||
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree [[W0:%.*]]) #[[ATTR0]] {
|
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]]) #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
|
||||||
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
|
||||||
|
@ -315,8 +315,8 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
|
||||||
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree noundef nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]]) #[[ATTR2]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[W0]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32* undef
|
; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = load i32, i32* %r0, align 4
|
%0 = load i32, i32* %r0, align 4
|
||||||
|
@ -348,7 +348,7 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[W0]]
|
; IS__TUNIT____-NEXT: ret i32* [[CALL1]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
|
||||||
|
@ -356,7 +356,7 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[W0]]) #[[ATTR3]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR4]]
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]]) #[[ATTR4]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[W0]]
|
; IS__CGSCC____-NEXT: ret i32* [[CALL1]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
|
%call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
|
||||||
|
|
|
@ -143,14 +143,16 @@ define void @test8_2(i32* %p) {
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2
|
||||||
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR0]] {
|
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: store i32 10, i32* [[P]], align 4
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) #[[ATTR1]]
|
||||||
|
; IS__TUNIT____-NEXT: store i32 10, i32* [[CALL]], align 4
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: store i32 10, i32* [[P]], align 4
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32* noalias nofree readnone "no-capture-maybe-returned" [[P]]) #[[ATTR11:[0-9]+]]
|
||||||
|
; IS__CGSCC____-NEXT: store i32 10, i32* [[CALL]], align 4
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -174,7 +176,7 @@ define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test9
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test9
|
||||||
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR4:[0-9]+]] {
|
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]]) #[[ATTR4:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>) #[[ATTR11:[0-9]+]]
|
; IS__CGSCC____-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>) #[[ATTR12:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>)
|
call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>)
|
||||||
|
@ -193,7 +195,7 @@ define <4 x i32> @test10(<4 x i32*> %ptrs) {
|
||||||
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test10
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test10
|
||||||
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR5:[0-9]+]] {
|
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR5:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR12:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 noundef 4, <4 x i1> noundef <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef) #[[ATTR13:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
|
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
|
||||||
;
|
;
|
||||||
%res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef)
|
%res = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> %ptrs, i32 4, <4 x i1><i1 true, i1 false, i1 true, i1 false>, <4 x i32>undef)
|
||||||
|
@ -231,7 +233,7 @@ define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nounwind
|
; IS__CGSCC____: Function Attrs: argmemonly nounwind
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test12_2
|
||||||
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] {
|
; IS__CGSCC____-SAME: (<4 x i32*> [[PTRS:%.*]]) #[[ATTR7:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR13:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]]) #[[ATTR14:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
|
; IS__CGSCC____-NEXT: ret <4 x i32> [[RES]]
|
||||||
;
|
;
|
||||||
%res = call <4 x i32> @test12_1(<4 x i32*> %ptrs)
|
%res = call <4 x i32> @test12_1(<4 x i32*> %ptrs)
|
||||||
|
@ -430,7 +432,25 @@ define void @ptr_uses(i8* %ptr) {
|
||||||
define void @ptr_use_chain(i8* %ptr) {
|
define void @ptr_use_chain(i8* %ptr) {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@ptr_use_chain
|
; CHECK-LABEL: define {{[^@]+}}@ptr_use_chain
|
||||||
; CHECK-SAME: (i8* [[PTR:%.*]]) {
|
; CHECK-SAME: (i8* [[PTR:%.*]]) {
|
||||||
; CHECK-NEXT: call void @escape_i8(i8* [[PTR]])
|
; CHECK-NEXT: [[BC0:%.*]] = bitcast i8* [[PTR]] to i32*
|
||||||
|
; CHECK-NEXT: [[BC1:%.*]] = bitcast i32* [[BC0]] to i8*
|
||||||
|
; CHECK-NEXT: [[BC2:%.*]] = bitcast i8* [[BC1]] to i32*
|
||||||
|
; CHECK-NEXT: [[BC3:%.*]] = bitcast i32* [[BC2]] to i8*
|
||||||
|
; CHECK-NEXT: [[BC4:%.*]] = bitcast i8* [[BC3]] to i32*
|
||||||
|
; CHECK-NEXT: [[BC5:%.*]] = bitcast i32* [[BC4]] to i8*
|
||||||
|
; CHECK-NEXT: [[BC6:%.*]] = bitcast i8* [[BC5]] to i32*
|
||||||
|
; CHECK-NEXT: [[BC7:%.*]] = bitcast i32* [[BC6]] to i8*
|
||||||
|
; CHECK-NEXT: [[BC8:%.*]] = bitcast i8* [[BC7]] to i32*
|
||||||
|
; CHECK-NEXT: [[BC9:%.*]] = bitcast i32* [[BC8]] to i8*
|
||||||
|
; CHECK-NEXT: [[ABC2:%.*]] = bitcast i8* [[BC9]] to i32*
|
||||||
|
; CHECK-NEXT: [[ABC3:%.*]] = bitcast i32* [[ABC2]] to i8*
|
||||||
|
; CHECK-NEXT: [[ABC4:%.*]] = bitcast i8* [[ABC3]] to i32*
|
||||||
|
; CHECK-NEXT: [[ABC5:%.*]] = bitcast i32* [[ABC4]] to i8*
|
||||||
|
; CHECK-NEXT: [[ABC6:%.*]] = bitcast i8* [[ABC5]] to i32*
|
||||||
|
; CHECK-NEXT: [[ABC7:%.*]] = bitcast i32* [[ABC6]] to i8*
|
||||||
|
; CHECK-NEXT: [[ABC8:%.*]] = bitcast i8* [[ABC7]] to i32*
|
||||||
|
; CHECK-NEXT: [[ABC9:%.*]] = bitcast i32* [[ABC8]] to i8*
|
||||||
|
; CHECK-NEXT: call void @escape_i8(i8* [[ABC9]])
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
%bc0 = bitcast i8* %ptr to i32*
|
%bc0 = bitcast i8* %ptr to i32*
|
||||||
|
@ -498,7 +518,8 @@ define i32 @read_only_constant_mem() {
|
||||||
; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn }
|
; IS__CGSCC____: attributes #[[ATTR8]] = { argmemonly nofree norecurse nounwind willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR9]] = { readnone }
|
; IS__CGSCC____: attributes #[[ATTR9]] = { readnone }
|
||||||
; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind readonly }
|
; IS__CGSCC____: attributes #[[ATTR10]] = { nounwind readonly }
|
||||||
; IS__CGSCC____: attributes #[[ATTR11]] = { willreturn writeonly }
|
; IS__CGSCC____: attributes #[[ATTR11]] = { readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR12]] = { readonly willreturn }
|
; IS__CGSCC____: attributes #[[ATTR12]] = { willreturn writeonly }
|
||||||
; IS__CGSCC____: attributes #[[ATTR13]] = { nounwind }
|
; IS__CGSCC____: attributes #[[ATTR13]] = { readonly willreturn }
|
||||||
|
; IS__CGSCC____: attributes #[[ATTR14]] = { nounwind }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
||||||
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
||||||
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
||||||
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
||||||
;
|
;
|
||||||
|
@ -64,15 +64,17 @@ define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_r1
|
||||||
; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR6:[0-9]+]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[R]]
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[CALL]]) #[[ATTR6:[0-9]+]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[CALL1]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r1
|
||||||
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[R]]) #[[ATTR7:[0-9]+]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[R]]
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]], i32 [[CALL]]) #[[ATTR7:[0-9]+]]
|
||||||
|
; IS__CGSCC____-NEXT: ret i32 [[CALL1]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 @sink_r0(i32 %r)
|
%call = call i32 @sink_r0(i32 %r)
|
||||||
|
@ -88,18 +90,20 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__TUNIT____: if.then:
|
; IS__TUNIT____: if.then:
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5]]
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__TUNIT____: if.then3:
|
; IS__TUNIT____: if.then3:
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: if.end12:
|
; IS__TUNIT____: if.end12:
|
||||||
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
||||||
|
@ -110,31 +114,33 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
||||||
; IS__TUNIT____: cond.end:
|
; IS__TUNIT____: cond.end:
|
||||||
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[R]]
|
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_r2
|
||||||
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__CGSCC____: if.then:
|
; IS__CGSCC____: if.then:
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__CGSCC____: if.then3:
|
; IS__CGSCC____: if.then3:
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
|
||||||
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[R]], i32 undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: if.end12:
|
; IS__CGSCC____: if.end12:
|
||||||
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
||||||
|
@ -145,11 +151,11 @@ define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
||||||
; IS__CGSCC____: cond.end:
|
; IS__CGSCC____: cond.end:
|
||||||
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[R]]
|
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp sgt i32 %a, %b
|
%cmp = icmp sgt i32 %a, %b
|
||||||
|
@ -203,18 +209,20 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__TUNIT____: if.then:
|
; IS__TUNIT____: if.then:
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR5]]
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__TUNIT____: if.then3:
|
; IS__TUNIT____: if.then3:
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[R]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[R]], i32 [[B]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[B]], i32 [[B]], i32 undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: if.end12:
|
; IS__TUNIT____: if.end12:
|
||||||
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
||||||
|
@ -225,24 +233,33 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
||||||
; IS__TUNIT____: cond.end:
|
; IS__TUNIT____: cond.end:
|
||||||
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
|
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX
|
||||||
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__CGSCC____: if.then:
|
; IS__CGSCC____: if.then:
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]]) #[[ATTR6]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]], i32 [[CALL]]) #[[ATTR8:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__CGSCC____: if.then3:
|
; IS__CGSCC____: if.then3:
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR8]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]], i32 [[R]]) #[[ATTR8]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[CALL6]], i32 undef) #[[ATTR8]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]], i32 undef) #[[ATTR8]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32 [[CALL7]], i32 [[CALL8]]) #[[ATTR8]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32 [[CALL9]], i32 undef) #[[ATTR8]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: if.end12:
|
; IS__CGSCC____: if.end12:
|
||||||
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
|
||||||
|
@ -250,12 +267,13 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
|
||||||
; IS__CGSCC____: cond.true:
|
; IS__CGSCC____: cond.true:
|
||||||
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
|
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
|
||||||
; IS__CGSCC____: cond.false:
|
; IS__CGSCC____: cond.false:
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]], i32 [[R]]) #[[ATTR8]]
|
||||||
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
||||||
; IS__CGSCC____: cond.end:
|
; IS__CGSCC____: cond.end:
|
||||||
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[R]], [[IF_THEN]] ], [ [[B]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
|
; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -343,17 +361,19 @@ entry:
|
||||||
define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
|
define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1
|
||||||
; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR5]]
|
||||||
; IS__TUNIT____-NEXT: ret double* [[R]]
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR6]]
|
||||||
|
; IS__TUNIT____-NEXT: ret double* [[CALL1]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1
|
||||||
; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR2:[0-9]+]] {
|
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
||||||
; IS__CGSCC____-NEXT: ret double* [[R]]
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR7]]
|
||||||
|
; IS__CGSCC____-NEXT: ret double* [[CALL1]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call double* @ptr_sink_r0(double* %r)
|
%call = call double* @ptr_sink_r0(double* %r)
|
||||||
|
@ -364,23 +384,25 @@ entry:
|
||||||
define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
|
define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2
|
||||||
; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__TUNIT____: if.then:
|
; IS__TUNIT____: if.then:
|
||||||
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR5]]
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__TUNIT____: if.then3:
|
; IS__TUNIT____: if.then3:
|
||||||
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[CALL5]], double* noalias nofree readnone [[CALL7]], double* noalias nofree readnone [[CALL8]]) #[[ATTR6]]
|
||||||
|
; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias nofree readnone [[CALL9]], double* noalias nocapture nofree readnone undef) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: if.end12:
|
; IS__TUNIT____: if.end12:
|
||||||
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
|
; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
|
||||||
|
@ -388,34 +410,36 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
|
||||||
; IS__TUNIT____: cond.true:
|
; IS__TUNIT____: cond.true:
|
||||||
; IS__TUNIT____-NEXT: br label [[COND_END:%.*]]
|
; IS__TUNIT____-NEXT: br label [[COND_END:%.*]]
|
||||||
; IS__TUNIT____: cond.false:
|
; IS__TUNIT____: cond.false:
|
||||||
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
; IS__TUNIT____-NEXT: br label [[COND_END]]
|
||||||
; IS__TUNIT____: cond.end:
|
; IS__TUNIT____: cond.end:
|
||||||
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
; IS__TUNIT____-NEXT: br label [[RETURN]]
|
||||||
; IS__TUNIT____: return:
|
; IS__TUNIT____: return:
|
||||||
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__TUNIT____-NEXT: ret double* [[R]]
|
; IS__TUNIT____-NEXT: ret double* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2
|
||||||
; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]], double* nocapture nofree readnone [[B:%.*]], double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__CGSCC____: if.then:
|
; IS__CGSCC____: if.then:
|
||||||
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR6]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[B]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_END12:%.*]]
|
||||||
; IS__CGSCC____: if.then3:
|
; IS__CGSCC____: if.then3:
|
||||||
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call double* @ptr_sink_r0(double* noalias nofree readnone "no-capture-maybe-returned" [[B]])
|
||||||
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[R]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[A]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[B]], double* noalias nocapture nofree readnone [[R]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[CALL5]], double* noalias nofree readnone [[CALL7]], double* noalias nofree readnone [[CALL8]]) #[[ATTR7]]
|
||||||
|
; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double* @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias nofree readnone [[CALL9]], double* noalias nocapture nofree readnone undef) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: if.end12:
|
; IS__CGSCC____: if.end12:
|
||||||
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
|
; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
|
||||||
|
@ -423,14 +447,14 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
|
||||||
; IS__CGSCC____: cond.true:
|
; IS__CGSCC____: cond.true:
|
||||||
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
|
; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
|
||||||
; IS__CGSCC____: cond.false:
|
; IS__CGSCC____: cond.false:
|
||||||
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nocapture nofree readnone [[A]], double* noalias nocapture nofree readnone [[B]], double* noalias nofree readnone "no-capture-maybe-returned" [[R]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree readnone [[B]], double* noalias nofree readnone [[R]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
; IS__CGSCC____-NEXT: br label [[COND_END]]
|
||||||
; IS__CGSCC____: cond.end:
|
; IS__CGSCC____: cond.end:
|
||||||
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[R]], [[COND_FALSE]] ]
|
; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]], [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
|
||||||
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
; IS__CGSCC____-NEXT: br label [[RETURN]]
|
||||||
; IS__CGSCC____: return:
|
; IS__CGSCC____: return:
|
||||||
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[R]], [[IF_THEN]] ], [ [[R]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
|
||||||
; IS__CGSCC____-NEXT: ret double* [[R]]
|
; IS__CGSCC____-NEXT: ret double* [[RETVAL_0]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp ugt double* %a, %b
|
%cmp = icmp ugt double* %a, %b
|
||||||
|
@ -492,7 +516,7 @@ define i32* @rt0(i32* %a) #0 {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
|
@ -519,7 +543,7 @@ define i32* @rt1(i32* %a) #0 {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR3]] {
|
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR2]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
|
@ -539,14 +563,14 @@ define i32* @rt2_helper(i32* %a) #0 {
|
||||||
; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[A]]
|
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper
|
||||||
; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[A]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[A]]
|
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @rt2(i32* %a, i32* %a)
|
%call = call i32* @rt2(i32* %a, i32* %a)
|
||||||
|
@ -564,12 +588,12 @@ define i32* @rt2(i32* %a, i32 *%b) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
|
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[SEL]]
|
; IS__TUNIT____-NEXT: ret i32* [[SEL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2
|
||||||
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
|
@ -577,7 +601,7 @@ define i32* @rt2(i32* %a, i32 *%b) #0 {
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree readnone [[A]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[A]], [[IF_THEN]] ]
|
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[SEL]]
|
; IS__CGSCC____-NEXT: ret i32* [[SEL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -598,17 +622,17 @@ if.end:
|
||||||
define i32* @rt3_helper(i32* %a, i32* %b) #0 {
|
define i32* @rt3_helper(i32* %a, i32* %b) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3_helper
|
||||||
; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[B]]
|
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3_helper
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[B]]
|
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%call = call i32* @rt3(i32* %a, i32* %b)
|
%call = call i32* @rt3(i32* %a, i32* %b)
|
||||||
|
@ -618,29 +642,29 @@ entry:
|
||||||
define i32* @rt3(i32* %a, i32 *%b) #0 {
|
define i32* @rt3(i32* %a, i32 *%b) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@rt3
|
||||||
; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__TUNIT____: if.then:
|
; IS__TUNIT____: if.then:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
|
; IS__TUNIT____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[B]]
|
; IS__TUNIT____-NEXT: ret i32* [[SEL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@rt3
|
||||||
; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
|
||||||
; IS__CGSCC____: if.then:
|
; IS__CGSCC____: if.then:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nocapture nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nofree readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned" [[B]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]
|
; IS__CGSCC____-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [ [[CALL]], [[IF_THEN]] ]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[B]]
|
; IS__CGSCC____-NEXT: ret i32* [[SEL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32* %a, null
|
%cmp = icmp eq i32* %a, null
|
||||||
|
@ -675,8 +699,8 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_unknown_fn
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_unknown_fn
|
||||||
; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR4:[0-9]+]] {
|
; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR8:[0-9]+]]
|
; IS__CGSCC____-NEXT: tail call void @unknown_fn(i32* (i32*)* noundef nonnull @calls_unknown_fn) #[[ATTR9:[0-9]+]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
||||||
;
|
;
|
||||||
tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
|
tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
|
||||||
|
@ -698,17 +722,11 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
|
||||||
; Verify the maybe-redefined function is not annotated:
|
; Verify the maybe-redefined function is not annotated:
|
||||||
;
|
;
|
||||||
define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
|
define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
; CHECK: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn
|
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn
|
||||||
; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
|
; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[R]]
|
||||||
;
|
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn
|
|
||||||
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
|
|
||||||
; IS__CGSCC____-NEXT: entry:
|
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
ret i32* %r
|
ret i32* %r
|
||||||
|
@ -724,9 +742,9 @@ define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
|
||||||
; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR4]] {
|
; IS__CGSCC____-SAME: (i32* returned [[R:%.*]]) #[[ATTR3]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR8]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]]) #[[ATTR9]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -747,17 +765,11 @@ entry:
|
||||||
; Verify the maybe-redefined function is not annotated:
|
; Verify the maybe-redefined function is not annotated:
|
||||||
;
|
;
|
||||||
define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
|
define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
; CHECK: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
|
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2
|
||||||
; IS__TUNIT____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
|
; CHECK-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[R]]
|
; CHECK-NEXT: ret i32* [[R]]
|
||||||
;
|
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@maybe_redefined_fn2
|
|
||||||
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
|
|
||||||
; IS__CGSCC____-NEXT: entry:
|
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[R]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
ret i32* %r
|
ret i32* %r
|
||||||
|
@ -773,9 +785,9 @@ define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
|
||||||
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR4]] {
|
; IS__CGSCC____-SAME: (i32* [[R:%.*]]) #[[ATTR3]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR8]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]]) #[[ATTR9]]
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
|
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
|
@ -803,7 +815,10 @@ define double @select_and_phi(double %b) #0 {
|
||||||
; IS__TUNIT____: if.then:
|
; IS__TUNIT____: if.then:
|
||||||
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: ret double [[B]]
|
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
|
||||||
|
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
|
||||||
|
; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
|
||||||
|
; IS__TUNIT____-NEXT: ret double [[SEL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@select_and_phi
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@select_and_phi
|
||||||
|
@ -814,7 +829,10 @@ define double @select_and_phi(double %b) #0 {
|
||||||
; IS__CGSCC____: if.then:
|
; IS__CGSCC____: if.then:
|
||||||
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: ret double [[B]]
|
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
|
||||||
|
; IS__CGSCC____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
|
||||||
|
; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
|
||||||
|
; IS__CGSCC____-NEXT: ret double [[SEL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = fcmp ogt double %b, 0.000000e+00
|
%cmp = fcmp ogt double %b, 0.000000e+00
|
||||||
|
@ -852,11 +870,14 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR6]]
|
||||||
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
; IS__TUNIT____-NEXT: br label [[IF_END]]
|
||||||
; IS__TUNIT____: if.end:
|
; IS__TUNIT____: if.end:
|
||||||
; IS__TUNIT____-NEXT: ret double [[B]]
|
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double [ [[CALL]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
|
||||||
|
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
|
||||||
|
; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
|
||||||
|
; IS__TUNIT____-NEXT: ret double [[SEL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursion_select_and_phi
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursion_select_and_phi
|
||||||
; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR2]] {
|
; IS__CGSCC____-SAME: (i32 [[A:%.*]], double returned [[B:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: entry:
|
; IS__CGSCC____-NEXT: entry:
|
||||||
; IS__CGSCC____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1
|
; IS__CGSCC____-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
|
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
|
||||||
|
@ -865,7 +886,10 @@ define double @recursion_select_and_phi(i32 %a, double %b) #0 {
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]]
|
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32 [[DEC]], double [[B]]) #[[ATTR7]]
|
||||||
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
; IS__CGSCC____-NEXT: br label [[IF_END]]
|
||||||
; IS__CGSCC____: if.end:
|
; IS__CGSCC____: if.end:
|
||||||
; IS__CGSCC____-NEXT: ret double [[B]]
|
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double [ [[CALL]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
|
||||||
|
; IS__CGSCC____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
|
||||||
|
; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
|
||||||
|
; IS__CGSCC____-NEXT: ret double [[SEL]]
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%dec = add nsw i32 %a, -1
|
%dec = add nsw i32 %a, -1
|
||||||
|
@ -1183,29 +1207,17 @@ ret_undef1:
|
||||||
declare i32* @unknown(i32*)
|
declare i32* @unknown(i32*)
|
||||||
|
|
||||||
define i32* @ret_arg_or_unknown(i32* %b) #0 {
|
define i32* @ret_arg_or_unknown(i32* %b) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
; CHECK: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
|
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
|
||||||
; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
|
; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
||||||
; IS__TUNIT____: ret_arg:
|
; CHECK: ret_arg:
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[B]]
|
; CHECK-NEXT: ret i32* [[B]]
|
||||||
; IS__TUNIT____: ret_unknown:
|
; CHECK: ret_unknown:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
|
; CHECK-NEXT: ret i32* [[CALL]]
|
||||||
;
|
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown
|
|
||||||
; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
|
|
||||||
; IS__CGSCC____-NEXT: entry:
|
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
|
||||||
; IS__CGSCC____: ret_arg:
|
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[B]]
|
|
||||||
; IS__CGSCC____: ret_unknown:
|
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[CALL]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32* %b, null
|
%cmp = icmp eq i32* %b, null
|
||||||
|
@ -1220,35 +1232,20 @@ ret_unknown:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
|
define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
; CHECK: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
|
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
|
||||||
; IS__TUNIT____-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
|
; CHECK-SAME: (i32* [[B:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
||||||
; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
||||||
; IS__TUNIT____: ret_arg:
|
; CHECK: ret_arg:
|
||||||
; IS__TUNIT____-NEXT: br label [[R:%.*]]
|
; CHECK-NEXT: br label [[R:%.*]]
|
||||||
; IS__TUNIT____: ret_unknown:
|
; CHECK: ret_unknown:
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
||||||
; IS__TUNIT____-NEXT: br label [[R]]
|
; CHECK-NEXT: br label [[R]]
|
||||||
; IS__TUNIT____: r:
|
; CHECK: r:
|
||||||
; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
|
; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[PHI]]
|
; CHECK-NEXT: ret i32* [[PHI]]
|
||||||
;
|
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
|
|
||||||
; IS__CGSCC____-SAME: (i32* [[B:%.*]]) #[[ATTR4]] {
|
|
||||||
; IS__CGSCC____-NEXT: entry:
|
|
||||||
; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
|
|
||||||
; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNKNOWN:%.*]]
|
|
||||||
; IS__CGSCC____: ret_arg:
|
|
||||||
; IS__CGSCC____-NEXT: br label [[R:%.*]]
|
|
||||||
; IS__CGSCC____: ret_unknown:
|
|
||||||
; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
|
|
||||||
; IS__CGSCC____-NEXT: br label [[R]]
|
|
||||||
; IS__CGSCC____: r:
|
|
||||||
; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [ [[CALL]], [[RET_UNKNOWN]] ]
|
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[PHI]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
%cmp = icmp eq i32* %b, null
|
%cmp = icmp eq i32* %b, null
|
||||||
|
@ -1411,35 +1408,20 @@ r:
|
||||||
declare void @noreturn() noreturn;
|
declare void @noreturn() noreturn;
|
||||||
|
|
||||||
define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
|
define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
|
||||||
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
|
; CHECK: Function Attrs: noinline nounwind uwtable
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi3
|
; CHECK-LABEL: define {{[^@]+}}@deadblockphi3
|
||||||
; IS__TUNIT____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
|
; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
|
; CHECK-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
|
||||||
; IS__TUNIT____: unreachablecall:
|
; CHECK: unreachablecall:
|
||||||
; IS__TUNIT____-NEXT: call void @noreturn() #[[ATTR4:[0-9]+]]
|
; CHECK-NEXT: call void @noreturn() #[[ATTR4:[0-9]+]]
|
||||||
; IS__TUNIT____-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; IS__TUNIT____: unreachableblock2:
|
; CHECK: unreachableblock2:
|
||||||
; IS__TUNIT____-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; IS__TUNIT____: unreachableblock3:
|
; CHECK: unreachableblock3:
|
||||||
; IS__TUNIT____-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; IS__TUNIT____: r:
|
; CHECK: r:
|
||||||
; IS__TUNIT____-NEXT: ret i32 [[A]]
|
; CHECK-NEXT: ret i32 [[A]]
|
||||||
;
|
|
||||||
; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
|
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi3
|
|
||||||
; IS__CGSCC____-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]]) #[[ATTR4]] {
|
|
||||||
; IS__CGSCC____-NEXT: entry:
|
|
||||||
; IS__CGSCC____-NEXT: br i1 [[C]], label [[R:%.*]], label [[UNREACHABLECALL:%.*]]
|
|
||||||
; IS__CGSCC____: unreachablecall:
|
|
||||||
; IS__CGSCC____-NEXT: call void @noreturn() #[[ATTR5:[0-9]+]]
|
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
|
||||||
; IS__CGSCC____: unreachableblock2:
|
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
|
||||||
; IS__CGSCC____: unreachableblock3:
|
|
||||||
; IS__CGSCC____-NEXT: unreachable
|
|
||||||
; IS__CGSCC____: r:
|
|
||||||
; IS__CGSCC____-NEXT: ret i32 [[A]]
|
|
||||||
;
|
;
|
||||||
entry:
|
entry:
|
||||||
br i1 %c, label %r, label %unreachablecall
|
br i1 %c, label %r, label %unreachablecall
|
||||||
|
@ -1504,10 +1486,10 @@ define i32 @exact(i32* align 8 %a, i32* align 8 %b) {
|
||||||
; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2)
|
; CHECK-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 noundef 2)
|
||||||
; CHECK-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]])
|
; CHECK-NEXT: [[C3:%.*]] = call align 32 i32* @non_exact_3(i32* align 32 [[A]])
|
||||||
; CHECK-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]])
|
; CHECK-NEXT: [[C4:%.*]] = call align 16 i32* @non_exact_4(i32* align 32 [[B]])
|
||||||
; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[A]], align 32
|
; CHECK-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32
|
||||||
; CHECK-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
|
; CHECK-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
|
||||||
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
|
; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
|
||||||
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2
|
; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]]
|
||||||
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
|
; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
|
||||||
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
|
; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
|
||||||
; CHECK-NEXT: ret i32 [[ADD4]]
|
; CHECK-NEXT: ret i32 [[ADD4]]
|
||||||
|
@ -1620,18 +1602,19 @@ attributes #0 = { noinline nounwind uwtable }
|
||||||
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree noinline noreturn nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR3]] = { noinline nounwind uwtable }
|
; IS__TUNIT____: attributes #[[ATTR3]] = { noinline nounwind uwtable }
|
||||||
; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn }
|
; IS__TUNIT____: attributes #[[ATTR4]] = { noreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR5:[0-9]+]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT____: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nosync nounwind readnone }
|
; IS__TUNIT____: attributes #[[ATTR6]] = { nofree nosync nounwind readnone }
|
||||||
; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind }
|
; IS__TUNIT____: attributes #[[ATTR7]] = { nounwind }
|
||||||
; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nounwind readnone }
|
; IS__TUNIT____: attributes #[[ATTR8:[0-9]+]] = { nounwind readnone }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree noinline norecurse nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR1]] = { nofree noinline nosync nounwind readnone uwtable }
|
||||||
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline nosync nounwind readnone uwtable }
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR3]] = { nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn }
|
; IS__CGSCC____: attributes #[[ATTR3]] = { noinline nounwind uwtable }
|
||||||
; IS__CGSCC____: attributes #[[ATTR4]] = { noinline nounwind uwtable }
|
; IS__CGSCC____: attributes #[[ATTR4]] = { noreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR5]] = { noreturn }
|
; IS__CGSCC____: attributes #[[ATTR5:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR6:[0-9]+]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC____: attributes #[[ATTR6]] = { readnone willreturn }
|
||||||
; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
|
; IS__CGSCC____: attributes #[[ATTR7]] = { nofree nosync nounwind readnone }
|
||||||
; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind }
|
; IS__CGSCC____: attributes #[[ATTR8]] = { nounwind readnone }
|
||||||
|
; IS__CGSCC____: attributes #[[ATTR9]] = { nounwind }
|
||||||
;.
|
;.
|
||||||
|
|
|
@ -1086,12 +1086,12 @@ define i32 @violate_noundef_nonpointer() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: ret i32 undef
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_nonpointer
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR0]] {
|
; IS__CGSCC____-SAME: () #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: ret i32 undef
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
%ret = call i32 @argument_noundef1(i32 undef)
|
%ret = call i32 @argument_noundef1(i32 undef)
|
||||||
ret i32 %ret
|
ret i32 %ret
|
||||||
|
@ -1115,12 +1115,12 @@ define i32* @violate_noundef_pointer() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@violate_noundef_pointer
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
; IS__TUNIT____-SAME: () #[[ATTR0]] {
|
||||||
; IS__TUNIT____-NEXT: ret i32* undef
|
; IS__TUNIT____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@violate_noundef_pointer
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR0]] {
|
; IS__CGSCC____-SAME: () #[[ATTR0]] {
|
||||||
; IS__CGSCC____-NEXT: ret i32* undef
|
; IS__CGSCC____-NEXT: unreachable
|
||||||
;
|
;
|
||||||
%ret = call i32* @argument_noundef2(i32* undef)
|
%ret = call i32* @argument_noundef2(i32* undef)
|
||||||
ret i32* %ret
|
ret i32* %ret
|
||||||
|
|
|
@ -388,9 +388,9 @@ f:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @ipccp4(i1 %c) {
|
define i32 @ipccp4(i1 %c) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp4
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp4
|
||||||
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
|
||||||
; IS__TUNIT____: t:
|
; IS__TUNIT____: t:
|
||||||
; IS__TUNIT____-NEXT: br label [[F]]
|
; IS__TUNIT____-NEXT: br label [[F]]
|
||||||
|
@ -433,14 +433,21 @@ define internal i32* @test_inalloca(i32* inalloca(i32) %a) {
|
||||||
define i32* @complicated_args_inalloca(i32* %arg) {
|
define i32* @complicated_args_inalloca(i32* %arg) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_inalloca
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_inalloca
|
||||||
; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call nonnull dereferenceable(4) i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR1]]
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree writeonly inalloca(i32) "no-capture-maybe-returned" [[ARG]]) #[[ATTR1]]
|
||||||
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
|
; IS__TUNIT____-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_inalloca
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_inalloca
|
||||||
; IS__CGSCC____-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC_OPM-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: ret i32* [[ARG]]
|
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[ARG]]) #[[ATTR7:[0-9]+]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_inalloca
|
||||||
|
; IS__CGSCC_NPM-SAME: (i32* nofree noundef nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR1]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree noundef nonnull writeonly inalloca(i32) dereferenceable(4) "no-capture-maybe-returned" [[ARG]]) #[[ATTR6:[0-9]+]]
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
%call = call i32* @test_inalloca(i32* inalloca(i32) %arg)
|
%call = call i32* @test_inalloca(i32* inalloca(i32) %arg)
|
||||||
ret i32* %call
|
ret i32* %call
|
||||||
|
@ -464,27 +471,29 @@ define i32* @complicated_args_preallocated() {
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
||||||
; IS__TUNIT_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
|
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
|
||||||
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 536870912 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
|
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]]
|
; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
||||||
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__TUNIT_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]]
|
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call noundef nonnull align 536870912 dereferenceable(4) i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
|
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR1]] [ "preallocated"(token [[C]]) ]
|
||||||
; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]]
|
; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC_OPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
|
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR8:[0-9]+]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i32* null
|
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR9:[0-9]+]] [ "preallocated"(token [[C]]) ]
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
; IS__CGSCC_NPM-SAME: () #[[ATTR0:[0-9]+]] {
|
||||||
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR6:[0-9]+]]
|
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 noundef 1) #[[ATTR7:[0-9]+]]
|
||||||
; IS__CGSCC_NPM-NEXT: ret i32* null
|
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree noundef writeonly preallocated(i32) align 536870912 null) #[[ATTR8:[0-9]+]] [ "preallocated"(token [[C]]) ]
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i32* [[CALL]]
|
||||||
;
|
;
|
||||||
%c = call token @llvm.call.preallocated.setup(i32 1)
|
%c = call token @llvm.call.preallocated.setup(i32 1)
|
||||||
%call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)]
|
%call = call i32* @test_preallocated(i32* preallocated(i32) null) ["preallocated"(token %c)]
|
||||||
|
@ -495,7 +504,7 @@ define internal void @test_sret(%struct.X* sret(%struct.X) %a, %struct.X** %b) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sret
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sret
|
||||||
; IS__TUNIT____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 536870912 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR2:[0-9]+]] {
|
; IS__TUNIT____-SAME: (%struct.X* noalias nofree noundef nonnull writeonly sret([[STRUCT_X:%.*]]) align 536870912 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[B:%.*]]) #[[ATTR3:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8
|
; IS__TUNIT____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -513,14 +522,14 @@ define void @complicated_args_sret(%struct.X** %b) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_sret
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_sret
|
||||||
; IS__TUNIT_OPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR2]] {
|
; IS__TUNIT_OPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT_OPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR5:[0-9]+]]
|
; IS__TUNIT_OPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR6:[0-9]+]]
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT_OPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_sret
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_sret
|
||||||
; IS__TUNIT_NPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR2]] {
|
; IS__TUNIT_NPM-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT_NPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR4:[0-9]+]]
|
; IS__TUNIT_NPM-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree noundef writeonly sret([[STRUCT_X:%.*]]) align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]]) #[[ATTR5:[0-9]+]]
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__TUNIT_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
|
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
|
||||||
|
@ -533,10 +542,15 @@ define void @complicated_args_sret(%struct.X** %b) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal %struct.X* @test_nest(%struct.X* nest %a) {
|
define internal %struct.X* @test_nest(%struct.X* nest %a) {
|
||||||
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_nest
|
||||||
|
; IS__TUNIT____-SAME: (%struct.X* nest noalias nofree noundef readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
||||||
|
; IS__TUNIT____-NEXT: ret %struct.X* [[A]]
|
||||||
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_nest
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_nest
|
||||||
; IS__CGSCC____-SAME: (%struct.X* nest noalias nocapture nofree readnone align 536870912 [[A:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC____-SAME: (%struct.X* nest noalias nofree noundef readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]]) #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: ret %struct.X* undef
|
; IS__CGSCC____-NEXT: ret %struct.X* [[A]]
|
||||||
;
|
;
|
||||||
ret %struct.X* %a
|
ret %struct.X* %a
|
||||||
}
|
}
|
||||||
|
@ -544,12 +558,20 @@ define %struct.X* @complicated_args_nest() {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: ret %struct.X* null
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR1]]
|
||||||
|
; IS__TUNIT____-NEXT: ret %struct.X* [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_nest
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_nest
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR1]] {
|
; IS__CGSCC_OPM-SAME: () #[[ATTR1]] {
|
||||||
; IS__CGSCC____-NEXT: ret %struct.X* null
|
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR7]]
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret %struct.X* [[CALL]]
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_nest
|
||||||
|
; IS__CGSCC_NPM-SAME: () #[[ATTR1]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree noundef readnone align 536870912 null) #[[ATTR6]]
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret %struct.X* [[CALL]]
|
||||||
;
|
;
|
||||||
%call = call %struct.X* @test_nest(%struct.X* null)
|
%call = call %struct.X* @test_nest(%struct.X* null)
|
||||||
ret %struct.X* %call
|
ret %struct.X* %call
|
||||||
|
@ -601,7 +623,7 @@ define void @complicated_args_byval() {
|
||||||
define internal i8*@test_byval2(%struct.X* byval(%struct.X) %a) {
|
define internal i8*@test_byval2(%struct.X* byval(%struct.X) %a) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_byval2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_byval2
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR3:[0-9]+]] {
|
; IS__TUNIT____-SAME: () #[[ATTR4:[0-9]+]] {
|
||||||
; IS__TUNIT____-NEXT: [[L:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8
|
; IS__TUNIT____-NEXT: [[L:%.*]] = load i8*, i8** getelementptr inbounds ([[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0), align 8
|
||||||
; IS__TUNIT____-NEXT: ret i8* [[L]]
|
; IS__TUNIT____-NEXT: ret i8* [[L]]
|
||||||
;
|
;
|
||||||
|
@ -616,23 +638,22 @@ define internal i8*@test_byval2(%struct.X* byval(%struct.X) %a) {
|
||||||
ret i8* %l
|
ret i8* %l
|
||||||
}
|
}
|
||||||
define i8* @complicated_args_byval2() {
|
define i8* @complicated_args_byval2() {
|
||||||
;
|
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_byval2
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_byval2
|
||||||
; IS__TUNIT____-SAME: () #[[ATTR3]] {
|
; IS__TUNIT____-SAME: () #[[ATTR4]] {
|
||||||
; IS__TUNIT____-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR3]]
|
; IS__TUNIT____-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR4]]
|
||||||
; IS__TUNIT____-NEXT: ret i8* [[C]]
|
; IS__TUNIT____-NEXT: ret i8* [[C]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval2
|
||||||
; IS__CGSCC_OPM-SAME: () #[[ATTR3]] {
|
; IS__CGSCC_OPM-SAME: () #[[ATTR3]] {
|
||||||
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR8:[0-9]+]]
|
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR10:[0-9]+]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i8* [[C]]
|
; IS__CGSCC_OPM-NEXT: ret i8* [[C]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
|
||||||
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval2
|
||||||
; IS__CGSCC_NPM-SAME: () #[[ATTR3]] {
|
; IS__CGSCC_NPM-SAME: () #[[ATTR3]] {
|
||||||
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR7:[0-9]+]]
|
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i8* @test_byval2() #[[ATTR9:[0-9]+]]
|
||||||
; IS__CGSCC_NPM-NEXT: ret i8* [[C]]
|
; IS__CGSCC_NPM-NEXT: ret i8* [[C]]
|
||||||
;
|
;
|
||||||
%c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S)
|
%c = call i8* @test_byval2(%struct.X* byval(%struct.X) @S)
|
||||||
|
@ -642,7 +663,7 @@ define i8* @complicated_args_byval2() {
|
||||||
define void @fixpoint_changed(i32* %p) {
|
define void @fixpoint_changed(i32* %p) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
|
; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fixpoint_changed
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fixpoint_changed
|
||||||
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR4:[0-9]+]] {
|
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR5:[0-9]+]] {
|
||||||
; IS__TUNIT_OPM-NEXT: entry:
|
; IS__TUNIT_OPM-NEXT: entry:
|
||||||
; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]]
|
; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]]
|
||||||
; IS__TUNIT_OPM: for.cond:
|
; IS__TUNIT_OPM: for.cond:
|
||||||
|
@ -665,7 +686,7 @@ define void @fixpoint_changed(i32* %p) {
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fixpoint_changed
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fixpoint_changed
|
||||||
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR2]] {
|
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT_NPM-NEXT: entry:
|
; IS__TUNIT_NPM-NEXT: entry:
|
||||||
; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]]
|
; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]]
|
||||||
; IS__TUNIT_NPM: for.cond:
|
; IS__TUNIT_NPM: for.cond:
|
||||||
|
@ -856,13 +877,13 @@ define internal i8 @callee(i8 %a) {
|
||||||
define void @user_as3() {
|
define void @user_as3() {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@user_as3
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@user_as3
|
||||||
; IS__TUNIT_OPM-SAME: () #[[ATTR5]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR6]] {
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4
|
; IS__TUNIT_OPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT_OPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@user_as3
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@user_as3
|
||||||
; IS__TUNIT_NPM-SAME: () #[[ATTR4]] {
|
; IS__TUNIT_NPM-SAME: () #[[ATTR5]] {
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4
|
; IS__TUNIT_NPM-NEXT: store i32 0, i32 addrspace(3)* @ConstAS3Ptr, align 4
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__TUNIT_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -885,13 +906,13 @@ define void @user_as3() {
|
||||||
define void @user() {
|
define void @user() {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@user
|
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@user
|
||||||
; IS__TUNIT_OPM-SAME: () #[[ATTR5]] {
|
; IS__TUNIT_OPM-SAME: () #[[ATTR6]] {
|
||||||
; IS__TUNIT_OPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4
|
; IS__TUNIT_OPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4
|
||||||
; IS__TUNIT_OPM-NEXT: ret void
|
; IS__TUNIT_OPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@user
|
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@user
|
||||||
; IS__TUNIT_NPM-SAME: () #[[ATTR4]] {
|
; IS__TUNIT_NPM-SAME: () #[[ATTR5]] {
|
||||||
; IS__TUNIT_NPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4
|
; IS__TUNIT_NPM-NEXT: store i32 0, i32* addrspacecast (i32 addrspace(3)* @ConstAS3Ptr to i32*), align 4
|
||||||
; IS__TUNIT_NPM-NEXT: ret void
|
; IS__TUNIT_NPM-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -914,17 +935,11 @@ define void @user() {
|
||||||
|
|
||||||
|
|
||||||
define i1 @test_merge_with_undef_values_ptr(i1 %c) {
|
define i1 @test_merge_with_undef_values_ptr(i1 %c) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
|
||||||
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR6:[0-9]+]] {
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
|
||||||
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR2]]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i1 [[R1]]
|
; IS__TUNIT____-NEXT: ret i1 [[R1]]
|
||||||
;
|
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone
|
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
|
|
||||||
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR5:[0-9]+]] {
|
|
||||||
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i1 @undef_then_null(i1 [[C]]) #[[ATTR5]]
|
|
||||||
; IS__TUNIT_NPM-NEXT: ret i1 [[R1]]
|
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_merge_with_undef_values_ptr
|
||||||
|
@ -935,31 +950,18 @@ define i1 @test_merge_with_undef_values_ptr(i1 %c) {
|
||||||
ret i1 %r1
|
ret i1 %r1
|
||||||
}
|
}
|
||||||
define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
|
define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
|
||||||
; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||||
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@undef_then_null
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_then_null
|
||||||
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR6]] {
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP1:%.*]] = icmp eq i32* null, null
|
; IS__TUNIT____-NEXT: [[CMP1:%.*]] = icmp eq i32* null, null
|
||||||
; IS__TUNIT_OPM-NEXT: [[CMP2:%.*]] = icmp eq i1 [[CMP1]], false
|
; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp eq i1 [[CMP1]], false
|
||||||
; IS__TUNIT_OPM-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[C]]
|
; IS__TUNIT____-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[C]]
|
||||||
; IS__TUNIT_OPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
; IS__TUNIT____-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
; IS__TUNIT_OPM: a:
|
; IS__TUNIT____: a:
|
||||||
; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR6]]
|
; IS__TUNIT____-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR2]]
|
||||||
; IS__TUNIT_OPM-NEXT: ret i1 [[R2]]
|
; IS__TUNIT____-NEXT: ret i1 [[R2]]
|
||||||
; IS__TUNIT_OPM: b:
|
; IS__TUNIT____: b:
|
||||||
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP2]]
|
; IS__TUNIT____-NEXT: ret i1 [[CMP2]]
|
||||||
;
|
|
||||||
; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone
|
|
||||||
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@undef_then_null
|
|
||||||
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR5]] {
|
|
||||||
; IS__TUNIT_NPM-NEXT: [[CMP1:%.*]] = icmp eq i32* null, null
|
|
||||||
; IS__TUNIT_NPM-NEXT: [[CMP2:%.*]] = icmp eq i1 [[CMP1]], false
|
|
||||||
; IS__TUNIT_NPM-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[C]]
|
|
||||||
; IS__TUNIT_NPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
|
||||||
; IS__TUNIT_NPM: a:
|
|
||||||
; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR5]]
|
|
||||||
; IS__TUNIT_NPM-NEXT: ret i1 [[R2]]
|
|
||||||
; IS__TUNIT_NPM: b:
|
|
||||||
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP2]]
|
|
||||||
;
|
;
|
||||||
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_then_null
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_then_null
|
||||||
|
@ -969,7 +971,7 @@ define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
|
||||||
; IS__CGSCC_OPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
; IS__CGSCC_OPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
||||||
; IS__CGSCC_OPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
; IS__CGSCC_OPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
; IS__CGSCC_OPM: a:
|
; IS__CGSCC_OPM: a:
|
||||||
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR9:[0-9]+]]
|
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR11:[0-9]+]]
|
||||||
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
||||||
; IS__CGSCC_OPM: b:
|
; IS__CGSCC_OPM: b:
|
||||||
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
||||||
|
@ -982,7 +984,7 @@ define internal i1 @undef_then_null(i1 %c, i32* %i32Aptr, i32* %i32Bptr) {
|
||||||
; IS__CGSCC_NPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
; IS__CGSCC_NPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
||||||
; IS__CGSCC_NPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
; IS__CGSCC_NPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
; IS__CGSCC_NPM: a:
|
; IS__CGSCC_NPM: a:
|
||||||
; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR8:[0-9]+]]
|
; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call i1 @undef_then_null(i1 noundef false) #[[ATTR10:[0-9]+]]
|
||||||
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
||||||
; IS__CGSCC_NPM: b:
|
; IS__CGSCC_NPM: b:
|
||||||
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
||||||
|
@ -999,9 +1001,10 @@ b:
|
||||||
}
|
}
|
||||||
|
|
||||||
define i1 @test_merge_with_undef_values(i1 %c) {
|
define i1 @test_merge_with_undef_values(i1 %c) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_merge_with_undef_values
|
||||||
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
|
||||||
|
; IS__TUNIT____-NEXT: [[R1:%.*]] = call noundef i1 @undef_then_1(i1 [[C]]) #[[ATTR2]]
|
||||||
; IS__TUNIT____-NEXT: ret i1 false
|
; IS__TUNIT____-NEXT: ret i1 false
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
|
@ -1013,16 +1016,38 @@ define i1 @test_merge_with_undef_values(i1 %c) {
|
||||||
ret i1 %r1
|
ret i1 %r1
|
||||||
}
|
}
|
||||||
define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) {
|
define internal i1 @undef_then_1(i1 %c, i32 %i32A, i32 %i32B) {
|
||||||
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
|
||||||
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_then_1
|
||||||
|
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #[[ATTR2]] {
|
||||||
|
; IS__TUNIT____-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
||||||
|
; IS__TUNIT____-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
|
; IS__TUNIT____: a:
|
||||||
|
; IS__TUNIT____-NEXT: [[R2:%.*]] = call noundef i1 @undef_then_1(i1 noundef false) #[[ATTR2]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i1 false
|
||||||
|
; IS__TUNIT____: b:
|
||||||
|
; IS__TUNIT____-NEXT: ret i1 false
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_then_1
|
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@undef_then_1
|
||||||
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #[[ATTR1]] {
|
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]]) #[[ATTR6]] {
|
||||||
; IS__CGSCC____-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
; IS__CGSCC_OPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
||||||
; IS__CGSCC____-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
; IS__CGSCC_OPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
; IS__CGSCC____: a:
|
; IS__CGSCC_OPM: a:
|
||||||
; IS__CGSCC____-NEXT: ret i1 undef
|
; IS__CGSCC_OPM-NEXT: [[R2:%.*]] = call noundef i1 @undef_then_1(i1 noundef false) #[[ATTR11]]
|
||||||
; IS__CGSCC____: b:
|
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
||||||
; IS__CGSCC____-NEXT: ret i1 undef
|
; IS__CGSCC_OPM: b:
|
||||||
|
; IS__CGSCC_OPM-NEXT: ret i1 undef
|
||||||
|
;
|
||||||
|
; IS__CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@undef_then_1
|
||||||
|
; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]]) #[[ATTR5]] {
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[OR:%.*]] = or i1 false, [[C]]
|
||||||
|
; IS__CGSCC_NPM-NEXT: br i1 [[OR]], label [[A:%.*]], label [[B:%.*]]
|
||||||
|
; IS__CGSCC_NPM: a:
|
||||||
|
; IS__CGSCC_NPM-NEXT: [[R2:%.*]] = call noundef i1 @undef_then_1(i1 noundef false) #[[ATTR10]]
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
||||||
|
; IS__CGSCC_NPM: b:
|
||||||
|
; IS__CGSCC_NPM-NEXT: ret i1 undef
|
||||||
;
|
;
|
||||||
%cmp1 = icmp eq i32 %i32A, %i32B
|
%cmp1 = icmp eq i32 %i32A, %i32B
|
||||||
%cmp2 = icmp eq i1 %cmp1, false
|
%cmp2 = icmp eq i1 %cmp1, false
|
||||||
|
@ -1039,7 +1064,8 @@ define i32 @test_select(i32 %c) {
|
||||||
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_select
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_select
|
||||||
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
; IS__TUNIT____-SAME: (i32 [[C:%.*]]) #[[ATTR1]] {
|
||||||
; IS__TUNIT____-NEXT: ret i32 42
|
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @select() #[[ATTR1]]
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 [[CALL]]
|
||||||
;
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_select
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_select
|
||||||
|
@ -1051,6 +1077,11 @@ define i32 @test_select(i32 %c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal i32 @select(i1 %a, i32 %b, i32 %c) {
|
define internal i32 @select(i1 %a, i32 %b, i32 %c) {
|
||||||
|
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
|
||||||
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@select
|
||||||
|
; IS__TUNIT____-SAME: () #[[ATTR1]] {
|
||||||
|
; IS__TUNIT____-NEXT: ret i32 42
|
||||||
|
;
|
||||||
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@select
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@select
|
||||||
; IS__CGSCC____-SAME: () #[[ATTR1]] {
|
; IS__CGSCC____-SAME: () #[[ATTR1]] {
|
||||||
|
@ -1079,7 +1110,7 @@ define void @test_callee_is_undef(void (i32)* %fn) {
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_callee_is_undef
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_callee_is_undef
|
||||||
; IS__TUNIT____-SAME: (void (i32)* nocapture nofree [[FN:%.*]]) {
|
; IS__TUNIT____-SAME: (void (i32)* nocapture nofree [[FN:%.*]]) {
|
||||||
; IS__TUNIT____-NEXT: call void @callee_is_undef()
|
; IS__TUNIT____-NEXT: call void @callee_is_undef()
|
||||||
; IS__TUNIT____-NEXT: call void @unknown_calle_arg_is_undef(void (i32)* nocapture nofree [[FN]])
|
; IS__TUNIT____-NEXT: call void @unknown_calle_arg_is_undef(void (i32)* nocapture nofree [[FN]], i32 undef)
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_callee_is_undef
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_callee_is_undef
|
||||||
|
@ -1097,7 +1128,7 @@ define internal void @callee_is_undef(void ()* %fn) {
|
||||||
; IS__TUNIT____-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
;
|
;
|
||||||
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_is_undef
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_is_undef
|
||||||
; IS__CGSCC____-SAME: (void ()* nocapture nofree noundef nonnull [[FN:%.*]]) {
|
; IS__CGSCC____-SAME: (void ()* noalias nocapture nofree noundef nonnull [[FN:%.*]]) {
|
||||||
; IS__CGSCC____-NEXT: call void [[FN]]()
|
; IS__CGSCC____-NEXT: call void [[FN]]()
|
||||||
; IS__CGSCC____-NEXT: ret void
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -1106,10 +1137,15 @@ define internal void @callee_is_undef(void ()* %fn) {
|
||||||
}
|
}
|
||||||
define internal void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 %arg) {
|
define internal void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 %arg) {
|
||||||
;
|
;
|
||||||
; CHECK-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef
|
||||||
; CHECK-SAME: (void (i32)* nocapture nofree noundef nonnull [[FN:%.*]]) {
|
; IS__TUNIT____-SAME: (void (i32)* nocapture nofree noundef nonnull [[FN:%.*]], i32 [[ARG:%.*]]) {
|
||||||
; CHECK-NEXT: call void [[FN]](i32 undef)
|
; IS__TUNIT____-NEXT: call void [[FN]](i32 undef)
|
||||||
; CHECK-NEXT: ret void
|
; IS__TUNIT____-NEXT: ret void
|
||||||
|
;
|
||||||
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@unknown_calle_arg_is_undef
|
||||||
|
; IS__CGSCC____-SAME: (void (i32)* nocapture nofree noundef nonnull [[FN:%.*]]) {
|
||||||
|
; IS__CGSCC____-NEXT: call void [[FN]](i32 undef)
|
||||||
|
; IS__CGSCC____-NEXT: ret void
|
||||||
;
|
;
|
||||||
call void %fn(i32 %arg)
|
call void %fn(i32 %arg)
|
||||||
ret void
|
ret void
|
||||||
|
@ -1123,7 +1159,7 @@ define internal void @unknown_calle_arg_is_undef(void (i32)* %fn, i32 %arg) {
|
||||||
define internal void @f1(i8*** %a) {
|
define internal void @f1(i8*** %a) {
|
||||||
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
|
||||||
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
|
||||||
; IS__TUNIT____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR2]] {
|
; IS__TUNIT____-SAME: (i8*** nocapture nofree noundef nonnull writeonly align 8 dereferenceable(8) [[A:%.*]]) #[[ATTR3]] {
|
||||||
; IS__TUNIT____-NEXT: entry:
|
; IS__TUNIT____-NEXT: entry:
|
||||||
; IS__TUNIT____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0
|
; IS__TUNIT____-NEXT: [[X:%.*]] = getelementptr { [2 x i8*] }, { [2 x i8*] }* @g, i32 0, i32 0, i32 0
|
||||||
; IS__TUNIT____-NEXT: store i8** [[X]], i8*** [[A]], align 8
|
; IS__TUNIT____-NEXT: store i8** [[X]], i8*** [[A]], align 8
|
||||||
|
@ -1218,97 +1254,22 @@ define internal i1 @cmp_null_after_cast(i32 %a, i8 %b) {
|
||||||
ret i1 %c
|
ret i1 %c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
declare i8* @m()
|
|
||||||
|
|
||||||
define i32 @test(i1 %c) {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@test
|
|
||||||
; CHECK-SAME: (i1 [[C:%.*]]) {
|
|
||||||
; CHECK-NEXT: [[R1:%.*]] = call i32 @ctx_test1(i1 [[C]])
|
|
||||||
; CHECK-NEXT: [[R2:%.*]] = call i32 @ctx_test2(i1 [[C]]), !range [[RNG0:![0-9]+]]
|
|
||||||
; CHECK-NEXT: [[ADD:%.*]] = add i32 [[R1]], [[R2]]
|
|
||||||
; CHECK-NEXT: ret i32 [[ADD]]
|
|
||||||
;
|
|
||||||
%r1 = call i32 @ctx_test1(i1 %c)
|
|
||||||
%r2 = call i32 @ctx_test2(i1 %c)
|
|
||||||
%add = add i32 %r1, %r2
|
|
||||||
ret i32 %add
|
|
||||||
}
|
|
||||||
|
|
||||||
define internal i32 @ctx_test1(i1 %c) {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@ctx_test1
|
|
||||||
; CHECK-SAME: (i1 [[C:%.*]]) {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]
|
|
||||||
; CHECK: then:
|
|
||||||
; CHECK-NEXT: [[M:%.*]] = tail call i8* @m()
|
|
||||||
; CHECK-NEXT: [[I:%.*]] = ptrtoint i8* [[M]] to i64
|
|
||||||
; CHECK-NEXT: br label [[JOIN]]
|
|
||||||
; CHECK: join:
|
|
||||||
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: [[RET:%.*]] = trunc i64 [[PHI]] to i32
|
|
||||||
; CHECK-NEXT: ret i32 [[RET]]
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
br i1 %c, label %then, label %join
|
|
||||||
|
|
||||||
then:
|
|
||||||
%m = tail call i8* @m()
|
|
||||||
%i = ptrtoint i8* %m to i64
|
|
||||||
br label %join
|
|
||||||
|
|
||||||
join:
|
|
||||||
%phi = phi i64 [ %i, %then ], [ undef, %entry ]
|
|
||||||
%ret = trunc i64 %phi to i32
|
|
||||||
ret i32 %ret
|
|
||||||
}
|
|
||||||
|
|
||||||
define internal i32 @ctx_test2(i1 %c) {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@ctx_test2
|
|
||||||
; CHECK-SAME: (i1 [[C:%.*]]) {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[JOIN:%.*]]
|
|
||||||
; CHECK: then:
|
|
||||||
; CHECK-NEXT: [[M:%.*]] = tail call i8* @m()
|
|
||||||
; CHECK-NEXT: [[I:%.*]] = ptrtoint i8* [[M]] to i32
|
|
||||||
; CHECK-NEXT: br label [[JOIN]]
|
|
||||||
; CHECK: join:
|
|
||||||
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[I]], [[THEN]] ], [ undef, [[ENTRY:%.*]] ]
|
|
||||||
; CHECK-NEXT: [[RET:%.*]] = lshr i32 [[PHI]], 1
|
|
||||||
; CHECK-NEXT: ret i32 [[RET]]
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
br i1 %c, label %then, label %join
|
|
||||||
|
|
||||||
then:
|
|
||||||
%m = tail call i8* @m()
|
|
||||||
%i = ptrtoint i8* %m to i32
|
|
||||||
br label %join
|
|
||||||
|
|
||||||
join:
|
|
||||||
%phi = phi i32 [ %i, %then ], [ undef, %entry ]
|
|
||||||
%ret = lshr i32 %phi, 1
|
|
||||||
ret i32 %ret
|
|
||||||
|
|
||||||
uselistorder label %join, { 1, 0 }
|
|
||||||
}
|
|
||||||
|
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
; IS__TUNIT_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT_OPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT_OPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR3]] = { nofree nosync nounwind readonly willreturn }
|
; IS__TUNIT_OPM: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR4]] = { argmemonly nofree nosync nounwind writeonly }
|
; IS__TUNIT_OPM: attributes #[[ATTR4]] = { nofree nosync nounwind readonly willreturn }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT_OPM: attributes #[[ATTR5]] = { argmemonly nofree nosync nounwind writeonly }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone }
|
; IS__TUNIT_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__TUNIT_OPM: attributes #[[ATTR7]] = { willreturn }
|
; IS__TUNIT_OPM: attributes #[[ATTR7]] = { willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
; IS__TUNIT_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
; IS__TUNIT_NPM: attributes #[[ATTR1]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR2]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT_NPM: attributes #[[ATTR2]] = { nofree nosync nounwind readnone }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR3]] = { nofree nosync nounwind readonly willreturn }
|
; IS__TUNIT_NPM: attributes #[[ATTR3]] = { argmemonly nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn writeonly }
|
; IS__TUNIT_NPM: attributes #[[ATTR4]] = { nofree nosync nounwind readonly willreturn }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind readnone }
|
; IS__TUNIT_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind willreturn writeonly }
|
||||||
; IS__TUNIT_NPM: attributes #[[ATTR6]] = { willreturn }
|
; IS__TUNIT_NPM: attributes #[[ATTR6]] = { willreturn }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
||||||
|
@ -1318,9 +1279,11 @@ join:
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind writeonly }
|
; IS__CGSCC_OPM: attributes #[[ATTR4]] = { argmemonly nofree norecurse nosync nounwind writeonly }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
; IS__CGSCC_OPM: attributes #[[ATTR5]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR6]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR7]] = { readnone willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR8]] = { readonly willreturn }
|
; IS__CGSCC_OPM: attributes #[[ATTR8]] = { willreturn }
|
||||||
; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nofree nosync nounwind readnone }
|
; IS__CGSCC_OPM: attributes #[[ATTR9]] = { nounwind readnone willreturn }
|
||||||
|
; IS__CGSCC_OPM: attributes #[[ATTR10]] = { readonly willreturn }
|
||||||
|
; IS__CGSCC_OPM: attributes #[[ATTR11]] = { nofree nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR0]] = { nofree nosync nounwind willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR1]] = { nofree norecurse nosync nounwind readnone willreturn }
|
||||||
|
@ -1328,9 +1291,9 @@ join:
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR3]] = { nofree norecurse nosync nounwind readonly willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
; IS__CGSCC_NPM: attributes #[[ATTR4]] = { nofree norecurse nosync nounwind willreturn writeonly }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR5]] = { nofree nosync nounwind readnone willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR6]] = { readnone willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { readonly willreturn }
|
; IS__CGSCC_NPM: attributes #[[ATTR7]] = { willreturn }
|
||||||
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nofree nosync nounwind readnone }
|
; IS__CGSCC_NPM: attributes #[[ATTR8]] = { nounwind readnone willreturn }
|
||||||
;.
|
; IS__CGSCC_NPM: attributes #[[ATTR9]] = { readonly willreturn }
|
||||||
; CHECK: [[RNG0]] = !{i32 0, i32 -2147483648}
|
; IS__CGSCC_NPM: attributes #[[ATTR10]] = { nofree nosync nounwind readnone }
|
||||||
;.
|
;.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,234 +0,0 @@
|
||||||
; RUN: opt -passes=openmp-opt -pass-remarks=openmp-opt -pass-remarks-missed=openmp-opt -pass-remarks-analysis=openmp-opt -disable-output < %s 2>&1 | FileCheck %s
|
|
||||||
target triple = "nvptx64"
|
|
||||||
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c:11:1: Generic-mode kernel is executed with a customized state machine that requires a fallback [1 known parallel regions, 2 unkown parallel regions] (bad)
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c:13:5: State machine fallback caused by this call. If it is a false positive, use `__attribute__((assume("omp_no_openmp"))` (or "omp_no_parallelism")
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c:15:5: State machine fallback caused by this call. If it is a false positive, use `__attribute__((assume("omp_no_openmp"))` (or "omp_no_parallelism")
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c:20:1: Generic-mode kernel is executed with a customized state machine [1 known parallel regions] (good)
|
|
||||||
|
|
||||||
;; void unknown(void);
|
|
||||||
;; void known(void) {
|
|
||||||
;; #pragma omp parallel
|
|
||||||
;; {
|
|
||||||
;; unknown();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
;;
|
|
||||||
;; void test_fallback(void) {
|
|
||||||
;; #pragma omp target teams
|
|
||||||
;; {
|
|
||||||
;; unknown();
|
|
||||||
;; known();
|
|
||||||
;; unknown();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
;;
|
|
||||||
;; void no_openmp(void) __attribute__((assume("omp_no_openmp")));
|
|
||||||
;; void test_no_fallback(void) {
|
|
||||||
;; #pragma omp target teams
|
|
||||||
;; {
|
|
||||||
;; known();
|
|
||||||
;; known();
|
|
||||||
;; known();
|
|
||||||
;; no_openmp(); // make it non-spmd
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
@0 = private unnamed_addr constant [113 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;__omp_offloading_2a_d80d3d_test_fallback_l11;11;1;;\00", align 1
|
|
||||||
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([113 x i8], [113 x i8]* @0, i32 0, i32 0) }, align 8
|
|
||||||
@2 = private unnamed_addr constant [82 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;test_fallback;11;1;;\00", align 1
|
|
||||||
@3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([82 x i8], [82 x i8]* @2, i32 0, i32 0) }, align 8
|
|
||||||
@4 = private unnamed_addr constant [114 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;__omp_offloading_2a_d80d3d_test_fallback_l11;11;25;;\00", align 1
|
|
||||||
@5 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([114 x i8], [114 x i8]* @4, i32 0, i32 0) }, align 8
|
|
||||||
@__omp_offloading_2a_d80d3d_test_fallback_l11_exec_mode = weak constant i8 1
|
|
||||||
@6 = private unnamed_addr constant [116 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;__omp_offloading_2a_d80d3d_test_no_fallback_l20;20;1;;\00", align 1
|
|
||||||
@7 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([116 x i8], [116 x i8]* @6, i32 0, i32 0) }, align 8
|
|
||||||
@8 = private unnamed_addr constant [85 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;test_no_fallback;20;1;;\00", align 1
|
|
||||||
@9 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([85 x i8], [85 x i8]* @8, i32 0, i32 0) }, align 8
|
|
||||||
@10 = private unnamed_addr constant [117 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;__omp_offloading_2a_d80d3d_test_no_fallback_l20;20;25;;\00", align 1
|
|
||||||
@11 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([117 x i8], [117 x i8]* @10, i32 0, i32 0) }, align 8
|
|
||||||
@__omp_offloading_2a_d80d3d_test_no_fallback_l20_exec_mode = weak constant i8 1
|
|
||||||
@12 = private unnamed_addr constant [73 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;known;4;1;;\00", align 1
|
|
||||||
@13 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 2, i32 0, i8* getelementptr inbounds ([73 x i8], [73 x i8]* @12, i32 0, i32 0) }, align 8
|
|
||||||
@G = external global i32
|
|
||||||
@llvm.compiler.used = appending global [2 x i8*] [i8* @__omp_offloading_2a_d80d3d_test_fallback_l11_exec_mode, i8* @__omp_offloading_2a_d80d3d_test_no_fallback_l20_exec_mode], section "llvm.metadata"
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define weak void @__omp_offloading_2a_d80d3d_test_fallback_l11() local_unnamed_addr #0 !dbg !15 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs.i.i = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 false, i1 true, i1 true) #3, !dbg !18
|
|
||||||
%exec_user_code = icmp eq i32 %0, -1, !dbg !18
|
|
||||||
br i1 %exec_user_code, label %user_code.entry, label %common.ret, !dbg !18
|
|
||||||
|
|
||||||
common.ret: ; preds = %entry, %user_code.entry
|
|
||||||
ret void, !dbg !19
|
|
||||||
|
|
||||||
user_code.entry: ; preds = %entry
|
|
||||||
%1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @3) #3
|
|
||||||
call void @unknown() #6, !dbg !20
|
|
||||||
%2 = bitcast [0 x i8*]* %captured_vars_addrs.i.i to i8*
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
%4 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs.i.i, i64 0, i64 0, !dbg !23
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %3, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !23
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !26
|
|
||||||
call void @unknown() #6, !dbg !27
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* nonnull @5, i1 false, i1 true) #3, !dbg !28
|
|
||||||
br label %common.ret
|
|
||||||
}
|
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: convergent
|
|
||||||
declare void @unknown() local_unnamed_addr #1
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
|
||||||
define hidden void @known() local_unnamed_addr #2 !dbg !29 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @13)
|
|
||||||
%1 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs, i64 0, i64 0, !dbg !30
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* nonnull @13, i32 %0, i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** nonnull %1, i64 0) #3, !dbg !30
|
|
||||||
ret void, !dbg !31
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
|
||||||
declare i32 @__kmpc_global_thread_num(%struct.ident_t*) local_unnamed_addr #3
|
|
||||||
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: norecurse nounwind
|
|
||||||
define weak void @__omp_offloading_2a_d80d3d_test_no_fallback_l20() local_unnamed_addr #4 !dbg !32 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs.i2.i = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @7, i1 false, i1 true, i1 true) #3, !dbg !33
|
|
||||||
%exec_user_code = icmp eq i32 %0, -1, !dbg !33
|
|
||||||
br i1 %exec_user_code, label %user_code.entry, label %common.ret, !dbg !33
|
|
||||||
|
|
||||||
common.ret: ; preds = %entry, %user_code.entry
|
|
||||||
ret void, !dbg !34
|
|
||||||
|
|
||||||
user_code.entry: ; preds = %entry
|
|
||||||
%1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @9) #3
|
|
||||||
%2 = bitcast [0 x i8*]* %captured_vars_addrs.i2.i to i8*
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
%4 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs.i2.i, i64 0, i64 0, !dbg !35
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %3, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !35
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !39
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%5 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %5, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !40
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !42
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%6 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %6, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !43
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !45
|
|
||||||
call void @no_openmp()
|
|
||||||
call void @no_parallelism()
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* nonnull @11, i1 false, i1 true) #3, !dbg !46
|
|
||||||
br label %common.ret
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__2(i32* noalias nocapture nofree readnone %.global_tid., i32* noalias nocapture nofree readnone %.bound_tid.) #0 !dbg !47 {
|
|
||||||
entry:
|
|
||||||
call void @unknown() #6, !dbg !48
|
|
||||||
ret void, !dbg !49
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__2_wrapper(i16 zeroext %0, i32 %1) #0 !dbg !50 {
|
|
||||||
entry:
|
|
||||||
%global_args = alloca i8**, align 8
|
|
||||||
call void @__kmpc_get_shared_variables(i8*** nonnull %global_args) #3, !dbg !51
|
|
||||||
call void @unknown() #6, !dbg !52
|
|
||||||
ret void, !dbg !51
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @__kmpc_get_shared_variables(i8***) local_unnamed_addr
|
|
||||||
|
|
||||||
declare void @__kmpc_parallel_51(%struct.ident_t*, i32, i32, i32, i32, i8*, i8*, i8**, i64) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #5
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #5
|
|
||||||
|
|
||||||
declare void @no_openmp() #7
|
|
||||||
declare void @no_parallelism() #8
|
|
||||||
|
|
||||||
attributes #0 = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #2 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #3 = { nounwind }
|
|
||||||
attributes #4 = { norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #5 = { argmemonly nofree nosync nounwind willreturn }
|
|
||||||
attributes #6 = { convergent nounwind }
|
|
||||||
attributes #7 = { "llvm.assume"="omp_no_openmp" }
|
|
||||||
attributes #8 = { "llvm.assume"="omp_no_parallelism" }
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
|
||||||
!omp_offload.info = !{!3, !4}
|
|
||||||
!nvvm.annotations = !{!5, !6}
|
|
||||||
!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13}
|
|
||||||
!llvm.ident = !{!14}
|
|
||||||
|
|
||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: DebugDirectivesOnly, enums: !2, splitDebugInlining: false, nameTableKind: None)
|
|
||||||
!1 = !DIFile(filename: "custom_state_machines_remarks.c", directory: "/data/src/llvm-project")
|
|
||||||
!2 = !{}
|
|
||||||
!3 = !{i32 0, i32 42, i32 14159165, !"test_no_fallback", i32 20, i32 1}
|
|
||||||
!4 = !{i32 0, i32 42, i32 14159165, !"test_fallback", i32 11, i32 0}
|
|
||||||
!5 = !{void ()* @__omp_offloading_2a_d80d3d_test_fallback_l11, !"kernel", i32 1}
|
|
||||||
!6 = !{void ()* @__omp_offloading_2a_d80d3d_test_no_fallback_l20, !"kernel", i32 1}
|
|
||||||
!7 = !{i32 7, !"Dwarf Version", i32 2}
|
|
||||||
!8 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!9 = !{i32 1, !"wchar_size", i32 4}
|
|
||||||
!10 = !{i32 7, !"openmp", i32 50}
|
|
||||||
!11 = !{i32 7, !"openmp-device", i32 50}
|
|
||||||
!12 = !{i32 7, !"PIC Level", i32 2}
|
|
||||||
!13 = !{i32 7, !"frame-pointer", i32 2}
|
|
||||||
!14 = !{!"clang version 13.0.0"}
|
|
||||||
!15 = distinct !DISubprogram(name: "__omp_offloading_2a_d80d3d_test_fallback_l11", scope: !16, file: !16, line: 11, type: !17, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!16 = !DIFile(filename: "llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c", directory: "/data/src/llvm-project")
|
|
||||||
!17 = !DISubroutineType(types: !2)
|
|
||||||
!18 = !DILocation(line: 11, column: 1, scope: !15)
|
|
||||||
!19 = !DILocation(line: 0, scope: !15)
|
|
||||||
!20 = !DILocation(line: 13, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!21 = distinct !DISubprogram(name: "__omp_outlined__", scope: !16, file: !16, line: 11, type: !17, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!22 = distinct !DILocation(line: 11, column: 1, scope: !15)
|
|
||||||
!23 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !25)
|
|
||||||
!24 = distinct !DISubprogram(name: "known", scope: !16, file: !16, line: 3, type: !17, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!25 = distinct !DILocation(line: 14, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!26 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !25)
|
|
||||||
!27 = !DILocation(line: 15, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!28 = !DILocation(line: 11, column: 25, scope: !15)
|
|
||||||
!29 = distinct !DISubprogram(name: "known", scope: !16, file: !16, line: 3, type: !17, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!30 = !DILocation(line: 4, column: 1, scope: !29)
|
|
||||||
!31 = !DILocation(line: 8, column: 1, scope: !29)
|
|
||||||
!32 = distinct !DISubprogram(name: "__omp_offloading_2a_d80d3d_test_no_fallback_l20", scope: !16, file: !16, line: 20, type: !17, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!33 = !DILocation(line: 20, column: 1, scope: !32)
|
|
||||||
!34 = !DILocation(line: 0, scope: !32)
|
|
||||||
!35 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !36)
|
|
||||||
!36 = distinct !DILocation(line: 22, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!37 = distinct !DISubprogram(name: "__omp_outlined__1", scope: !16, file: !16, line: 20, type: !17, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!38 = distinct !DILocation(line: 20, column: 1, scope: !32)
|
|
||||||
!39 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !36)
|
|
||||||
!40 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !41)
|
|
||||||
!41 = distinct !DILocation(line: 23, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!42 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !41)
|
|
||||||
!43 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !44)
|
|
||||||
!44 = distinct !DILocation(line: 24, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!45 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !44)
|
|
||||||
!46 = !DILocation(line: 20, column: 25, scope: !32)
|
|
||||||
!47 = distinct !DISubprogram(name: "__omp_outlined__2", scope: !16, file: !16, line: 4, type: !17, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!48 = !DILocation(line: 6, column: 5, scope: !47)
|
|
||||||
!49 = !DILocation(line: 7, column: 3, scope: !47)
|
|
||||||
!50 = distinct !DISubprogram(linkageName: "__omp_outlined__2_wrapper", scope: !16, file: !16, line: 4, type: !17, scopeLine: 4, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!51 = !DILocation(line: 4, column: 1, scope: !50)
|
|
||||||
!52 = !DILocation(line: 6, column: 5, scope: !47, inlinedAt: !53)
|
|
||||||
!53 = distinct !DILocation(line: 4, column: 1, scope: !50)
|
|
|
@ -7,19 +7,15 @@ target triple = "nvptx64"
|
||||||
; CHECK: remark: globalization_remarks.c:5:7: Could not move globalized variable to the stack. Variable is potentially captured.
|
; CHECK: remark: globalization_remarks.c:5:7: Could not move globalized variable to the stack. Variable is potentially captured.
|
||||||
; CHECK: remark: globalization_remarks.c:5:7: Found thread data sharing on the GPU. Expect degraded performance due to data globalization.
|
; CHECK: remark: globalization_remarks.c:5:7: Found thread data sharing on the GPU. Expect degraded performance due to data globalization.
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
@S = external local_unnamed_addr global i8*
|
@S = external local_unnamed_addr global i8*
|
||||||
|
|
||||||
define void @foo() {
|
define void @foo() {
|
||||||
entry:
|
entry:
|
||||||
%c = call i32 @__kmpc_target_init(%struct.ident_t* null, i1 false, i1 true, i1 true)
|
|
||||||
%0 = call i8* @__kmpc_alloc_shared(i64 4), !dbg !10
|
%0 = call i8* @__kmpc_alloc_shared(i64 4), !dbg !10
|
||||||
%x_on_stack = bitcast i8* %0 to i32*
|
%x_on_stack = bitcast i8* %0 to i32*
|
||||||
%1 = bitcast i32* %x_on_stack to i8*
|
%1 = bitcast i32* %x_on_stack to i8*
|
||||||
call void @share(i8* %1)
|
call void @share(i8* %1)
|
||||||
call void @__kmpc_free_shared(i8* %0)
|
call void @__kmpc_free_shared(i8* %0)
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* null, i1 false, i1 true)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,8 +29,6 @@ declare i8* @__kmpc_alloc_shared(i64)
|
||||||
|
|
||||||
declare void @__kmpc_free_shared(i8*)
|
declare void @__kmpc_free_shared(i8*)
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1);
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1)
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
!llvm.dbg.cu = !{!0}
|
||||||
!llvm.module.flags = !{!3, !4, !5, !6}
|
!llvm.module.flags = !{!3, !4, !5, !6}
|
||||||
|
|
|
@ -7,28 +7,19 @@ target triple = "nvptx64"
|
||||||
; CHECK-REMARKS: remark: remove_globalization.c:4:2: Could not move globalized variable to the stack. Variable is potentially captured. Mark as noescape to override.
|
; CHECK-REMARKS: remark: remove_globalization.c:4:2: Could not move globalized variable to the stack. Variable is potentially captured. Mark as noescape to override.
|
||||||
; CHECK-REMARKS: remark: remove_globalization.c:2:2: Moving globalized variable to the stack.
|
; CHECK-REMARKS: remark: remove_globalization.c:2:2: Moving globalized variable to the stack.
|
||||||
; CHECK-REMARKS: remark: remove_globalization.c:6:2: Moving globalized variable to the stack.
|
; CHECK-REMARKS: remark: remove_globalization.c:6:2: Moving globalized variable to the stack.
|
||||||
; CHECK-REMARKS: remark: remove_globalization.c:4:2: Found thread data sharing on the GPU. Expect degraded performance due to data globalization.
|
|
||||||
|
|
||||||
@S = external local_unnamed_addr global i8*
|
@S = external local_unnamed_addr global i8*
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1)
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1)
|
|
||||||
|
|
||||||
define void @kernel() {
|
define void @kernel() {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@kernel() {
|
; CHECK-LABEL: define {{[^@]+}}@kernel() {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* nonnull null, i1 false, i1 false, i1 true)
|
|
||||||
; CHECK-NEXT: call void @foo() #[[ATTR0:[0-9]+]]
|
; CHECK-NEXT: call void @foo() #[[ATTR0:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @bar() #[[ATTR0]]
|
; CHECK-NEXT: call void @bar() #[[ATTR0]]
|
||||||
; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* nonnull null, i1 false, i1 true)
|
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
;
|
||||||
entry:
|
entry:
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* nonnull null, i1 false, i1 true, i1 true)
|
|
||||||
call void @foo()
|
call void @foo()
|
||||||
call void @bar()
|
call void @bar()
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* nonnull null, i1 false, i1 true)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +41,8 @@ define internal void @bar() {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@bar
|
; CHECK-LABEL: define {{[^@]+}}@bar
|
||||||
; CHECK-SAME: () #[[ATTR0]] {
|
; CHECK-SAME: () #[[ATTR0]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i8* @__kmpc_alloc_shared(i64 noundef 4) #[[ATTR0]], !dbg [[DBG8:![0-9]+]]
|
; CHECK-NEXT: [[TMP0:%.*]] = call i8* @__kmpc_alloc_shared(i64 noundef 4) #[[ATTR0]]
|
||||||
; CHECK-NEXT: call void @share(i8* nofree writeonly [[TMP0]]) #[[ATTR3:[0-9]+]]
|
; CHECK-NEXT: call void @share(i8* nofree writeonly [[TMP0]]) #[[ATTR2:[0-9]+]]
|
||||||
; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[TMP0]]) #[[ATTR0]]
|
; CHECK-NEXT: call void @__kmpc_free_shared(i8* [[TMP0]]) #[[ATTR0]]
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
;
|
;
|
||||||
|
@ -63,18 +54,13 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal void @use(i8* %x) {
|
define internal void @use(i8* %x) {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@use
|
|
||||||
; CHECK-SAME: (i8* noalias nocapture nofree readnone [[X:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define internal void @share(i8* %x) {
|
define internal void @share(i8* %x) {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@share
|
; CHECK-LABEL: define {{[^@]+}}@share
|
||||||
; CHECK-SAME: (i8* nofree writeonly [[X:%.*]]) #[[ATTR2:[0-9]+]] {
|
; CHECK-SAME: (i8* nofree writeonly [[X:%.*]]) #[[ATTR1:[0-9]+]] {
|
||||||
; CHECK-NEXT: entry:
|
; CHECK-NEXT: entry:
|
||||||
; CHECK-NEXT: store i8* [[X]], i8** @S, align 8
|
; CHECK-NEXT: store i8* [[X]], i8** @S, align 8
|
||||||
; CHECK-NEXT: ret void
|
; CHECK-NEXT: ret void
|
||||||
|
@ -85,12 +71,6 @@ entry:
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @unused() {
|
define void @unused() {
|
||||||
; CHECK-LABEL: define {{[^@]+}}@unused() {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = alloca i8, i64 4, align 1
|
|
||||||
; CHECK-NEXT: call void @use(i8* noalias readnone undef)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
entry:
|
||||||
%0 = call i8* @__kmpc_alloc_shared(i64 4), !dbg !14
|
%0 = call i8* @__kmpc_alloc_shared(i64 4), !dbg !14
|
||||||
call void @use(i8* %0)
|
call void @use(i8* %0)
|
||||||
|
|
|
@ -3,16 +3,10 @@
|
||||||
target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
|
target datalayout = "e-i64:64-i128:128-v16:16-v32:32-n16:32:64"
|
||||||
target triple = "nvptx64"
|
target triple = "nvptx64"
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
@S = external local_unnamed_addr global i8*
|
@S = external local_unnamed_addr global i8*
|
||||||
@0 = private unnamed_addr constant [113 x i8] c";llvm/test/Transforms/OpenMP/custom_state_machines_remarks.c;__omp_offloading_2a_d80d3d_test_fallback_l11;11;1;;\00", align 1
|
|
||||||
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([113 x i8], [113 x i8]* @0, i32 0, i32 0) }, align 8
|
|
||||||
|
|
||||||
; CHECK-REMARKS: remark: replace_globalization.c:5:7: Replaced globalized variable with 16 bytes of shared memory
|
; CHECK-REMARKS: remark: replace_globalization.c:5:7: Replaced globalized variable with 16 bytes of shared memory
|
||||||
; CHECK-REMARKS: remark: replace_globalization.c:5:14: Replaced globalized variable with 4 bytes of shared memory
|
; CHECK-REMARKS: remark: replace_globalization.c:5:14: Replaced globalized variable with 4 bytes of shared memory
|
||||||
; CHECK-REMARKS-NOT: 6 bytes
|
|
||||||
|
|
||||||
; CHECK: [[SHARED_X:@.+]] = internal addrspace(3) global [16 x i8] undef
|
; CHECK: [[SHARED_X:@.+]] = internal addrspace(3) global [16 x i8] undef
|
||||||
; CHECK: [[SHARED_Y:@.+]] = internal addrspace(3) global [4 x i8] undef
|
; CHECK: [[SHARED_Y:@.+]] = internal addrspace(3) global [4 x i8] undef
|
||||||
|
|
||||||
|
@ -20,30 +14,25 @@ target triple = "nvptx64"
|
||||||
; CHECK: call void @__kmpc_free_shared({{.*}})
|
; CHECK: call void @__kmpc_free_shared({{.*}})
|
||||||
define dso_local void @foo() {
|
define dso_local void @foo() {
|
||||||
entry:
|
entry:
|
||||||
%c = call i32 @__kmpc_target_init(%struct.ident_t* @1, i1 false, i1 true, i1 true)
|
|
||||||
%x = call i8* @__kmpc_alloc_shared(i64 4)
|
%x = call i8* @__kmpc_alloc_shared(i64 4)
|
||||||
%x_on_stack = bitcast i8* %x to i32*
|
%x_on_stack = bitcast i8* %x to i32*
|
||||||
%0 = bitcast i32* %x_on_stack to i8*
|
%0 = bitcast i32* %x_on_stack to i8*
|
||||||
call void @use(i8* %0)
|
call void @use(i8* %0)
|
||||||
call void @__kmpc_free_shared(i8* %x)
|
call void @__kmpc_free_shared(i8* %x)
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* @1, i1 false, i1 true)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @bar() {
|
define void @bar() {
|
||||||
%c = call i32 @__kmpc_target_init(%struct.ident_t* @1, i1 false, i1 true, i1 true)
|
|
||||||
call void @baz()
|
call void @baz()
|
||||||
call void @qux()
|
call void @qux()
|
||||||
call void @negative_qux_spmd()
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* @1, i1 false, i1 true)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: call void @use.internalized(i8* nofree writeonly addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* [[SHARED_X]], i32 0, i32 0) to i8*))
|
; CHECK: %{{.*}} = bitcast i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([16 x i8], [16 x i8] addrspace(3)* [[SHARED_X]], i32 0, i32 0) to i8*) to [4 x i32]*
|
||||||
define internal void @baz() {
|
define internal void @baz() {
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 false, i1 false, i1 true)
|
%tid = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
|
||||||
%cmp = icmp eq i32 %call, -1
|
%cmp = icmp eq i32 %tid, 0
|
||||||
br i1 %cmp, label %master, label %exit
|
br i1 %cmp, label %master, label %exit
|
||||||
master:
|
master:
|
||||||
%x = call i8* @__kmpc_alloc_shared(i64 16), !dbg !11
|
%x = call i8* @__kmpc_alloc_shared(i64 16), !dbg !11
|
||||||
|
@ -56,33 +45,23 @@ exit:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: call void @use.internalized(i8* nofree writeonly addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* [[SHARED_Y]], i32 0, i32 0) to i8*))
|
; CHECK: %{{.*}} = bitcast i8* addrspacecast (i8 addrspace(3)* getelementptr inbounds ([4 x i8], [4 x i8] addrspace(3)* [[SHARED_Y]], i32 0, i32 0) to i8*) to [4 x i32]*
|
||||||
define internal void @qux() {
|
define internal void @qux() {
|
||||||
entry:
|
entry:
|
||||||
%call = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 false, i1 true, i1 true)
|
%tid = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
|
||||||
%0 = icmp eq i32 %call, -1
|
%ntid = call i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
|
||||||
br i1 %0, label %master, label %exit
|
%warpsize = call i32 @llvm.nvvm.read.ptx.sreg.warpsize()
|
||||||
|
%0 = sub nuw i32 %warpsize, 1
|
||||||
|
%1 = sub nuw i32 %ntid, 1
|
||||||
|
%2 = xor i32 %0, -1
|
||||||
|
%master_tid = and i32 %1, %2
|
||||||
|
%3 = icmp eq i32 %tid, %master_tid
|
||||||
|
br i1 %3, label %master, label %exit
|
||||||
master:
|
master:
|
||||||
%y = call i8* @__kmpc_alloc_shared(i64 4), !dbg !12
|
%y = call i8* @__kmpc_alloc_shared(i64 4), !dbg !12
|
||||||
%y_on_stack = bitcast i8* %y to [4 x i32]*
|
%y_on_stack = bitcast i8* %y to [4 x i32]*
|
||||||
%1 = bitcast [4 x i32]* %y_on_stack to i8*
|
%4 = bitcast [4 x i32]* %y_on_stack to i8*
|
||||||
call void @use(i8* %1)
|
call void @use(i8* %4)
|
||||||
call void @__kmpc_free_shared(i8* %y)
|
|
||||||
br label %exit
|
|
||||||
exit:
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
define internal void @negative_qux_spmd() {
|
|
||||||
entry:
|
|
||||||
%call = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 true, i1 true, i1 true)
|
|
||||||
%0 = icmp eq i32 %call, -1
|
|
||||||
br i1 %0, label %master, label %exit
|
|
||||||
master:
|
|
||||||
%y = call i8* @__kmpc_alloc_shared(i64 6), !dbg !12
|
|
||||||
%y_on_stack = bitcast i8* %y to [6 x i32]*
|
|
||||||
%1 = bitcast [6 x i32]* %y_on_stack to i8*
|
|
||||||
call void @use(i8* %1)
|
|
||||||
call void @__kmpc_free_shared(i8* %y)
|
call void @__kmpc_free_shared(i8* %y)
|
||||||
br label %exit
|
br label %exit
|
||||||
exit:
|
exit:
|
||||||
|
@ -106,9 +85,6 @@ declare i32 @llvm.nvvm.read.ptx.sreg.ntid.x()
|
||||||
|
|
||||||
declare i32 @llvm.nvvm.read.ptx.sreg.warpsize()
|
declare i32 @llvm.nvvm.read.ptx.sreg.warpsize()
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1)
|
|
||||||
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1)
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
!llvm.dbg.cu = !{!0}
|
||||||
!llvm.module.flags = !{!3, !4, !5, !6}
|
!llvm.module.flags = !{!3, !4, !5, !6}
|
||||||
|
|
|
@ -3,41 +3,25 @@
|
||||||
; REQUIRES: asserts
|
; REQUIRES: asserts
|
||||||
; ModuleID = 'single_threaded_exeuction.c'
|
; ModuleID = 'single_threaded_exeuction.c'
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
define weak void @kernel() {
|
||||||
|
call void @__kmpc_kernel_init(i32 512, i16 1)
|
||||||
@0 = private unnamed_addr constant [1 x i8] c"\00", align 1
|
|
||||||
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @0, i32 0, i32 0) }, align 8
|
|
||||||
|
|
||||||
|
|
||||||
; CHECK-NOT: [openmp-opt] Basic block @kernel entry is executed by a single thread.
|
|
||||||
; CHECK: [openmp-opt] Basic block @kernel if.then is executed by a single thread.
|
|
||||||
; CHECK-NOT: [openmp-opt] Basic block @kernel if.else is executed by a single thread.
|
|
||||||
; CHECK-NOT: [openmp-opt] Basic block @kernel if.end is executed by a single thread.
|
|
||||||
define void @kernel() {
|
|
||||||
%call = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 false, i1 false, i1 false)
|
|
||||||
%cmp = icmp eq i32 %call, -1
|
|
||||||
br i1 %cmp, label %if.then, label %if.else
|
|
||||||
if.then:
|
|
||||||
call void @nvptx()
|
call void @nvptx()
|
||||||
call void @amdgcn()
|
call void @amdgcn()
|
||||||
br label %if.end
|
|
||||||
if.else:
|
|
||||||
br label %if.end
|
|
||||||
if.end:
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* null, i1 false, i1 true)
|
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; REMARKS: remark: single_threaded_execution.c:1:0: Could not internalize function. Some optimizations may not be possible.
|
; REMARKS: remark: single_threaded_execution.c:1:0: Could not internalize function. Some optimizations may not be possible.
|
||||||
; REMARKS-NOT: remark: single_threaded_execution.c:1:0: Could not internalize function. Some optimizations may not be possible.
|
; REMARKS-NOT: remark: single_threaded_execution.c:1:0: Could not internalize function. Some optimizations may not be possible.
|
||||||
|
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @nvptx entry is executed by a single thread.
|
; CHECK-NOT: [openmp-opt] Basic block @nvptx entry is executed by a single thread.
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @nvptx if.then is executed by a single thread.
|
; CHECK: [openmp-opt] Basic block @nvptx if.then is executed by a single thread.
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @nvptx if.end is executed by a single thread.
|
; CHECK-NOT: [openmp-opt] Basic block @nvptx if.end is executed by a single thread.
|
||||||
; Function Attrs: noinline
|
; Function Attrs: noinline
|
||||||
define internal void @nvptx() {
|
define internal void @nvptx() {
|
||||||
entry:
|
entry:
|
||||||
br i1 true, label %if.then, label %if.end
|
%call = call i32 @llvm.nvvm.read.ptx.sreg.tid.x()
|
||||||
|
%cmp = icmp eq i32 %call, 0
|
||||||
|
br i1 %cmp, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
call void @foo()
|
call void @foo()
|
||||||
|
@ -50,13 +34,15 @@ if.end:
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @amdgcn entry is executed by a single thread.
|
; CHECK-NOT: [openmp-opt] Basic block @amdgcn entry is executed by a single thread.
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @amdgcn if.then is executed by a single thread.
|
; CHECK: [openmp-opt] Basic block @amdgcn if.then is executed by a single thread.
|
||||||
; CHECK-DAG: [openmp-opt] Basic block @amdgcn if.end is executed by a single thread.
|
; CHECK-NOT: [openmp-opt] Basic block @amdgcn if.end is executed by a single thread.
|
||||||
; Function Attrs: noinline
|
; Function Attrs: noinline
|
||||||
define internal void @amdgcn() {
|
define internal void @amdgcn() {
|
||||||
entry:
|
entry:
|
||||||
br i1 false, label %if.then, label %if.end
|
%call = call i32 @llvm.amdgcn.workitem.id.x()
|
||||||
|
%cmp = icmp eq i32 %call, 0
|
||||||
|
br i1 %cmp, label %if.then, label %if.end
|
||||||
|
|
||||||
if.then:
|
if.then:
|
||||||
call void @foo()
|
call void @foo()
|
||||||
|
@ -101,10 +87,7 @@ declare i32 @llvm.nvvm.read.ptx.sreg.tid.x()
|
||||||
|
|
||||||
declare i32 @llvm.amdgcn.workitem.id.x()
|
declare i32 @llvm.amdgcn.workitem.id.x()
|
||||||
|
|
||||||
declare void @__kmpc_kernel_prepare_parallel(i8*)
|
declare void @__kmpc_kernel_init(i32, i16)
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1)
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1)
|
|
||||||
|
|
||||||
attributes #0 = { cold noinline }
|
attributes #0 = { cold noinline }
|
||||||
|
|
||||||
|
|
|
@ -1,214 +0,0 @@
|
||||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals
|
|
||||||
; RUN: opt -S -passes=openmp-opt < %s | FileCheck %s
|
|
||||||
|
|
||||||
;; void unknown(void);
|
|
||||||
;; void spmd_amenable(void) __attribute__((assume("ompx_spmd_amenable")))
|
|
||||||
;;
|
|
||||||
;; void sequential_loop() {
|
|
||||||
;; #pragma omp target teams
|
|
||||||
;; {
|
|
||||||
;; for (int i = 0; i < 100; ++i) {
|
|
||||||
;; #pragma omp parallel
|
|
||||||
;; {
|
|
||||||
;; unknown();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
; spmd_amenable();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
|
|
||||||
target triple = "nvptx64"
|
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
@0 = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00", align 1
|
|
||||||
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @0, i32 0, i32 0) }, align 8
|
|
||||||
@__omp_offloading_2c_38c77_sequential_loop_l4_exec_mode = weak constant i8 1
|
|
||||||
@llvm.compiler.used = appending global [1 x i8*] [i8* @__omp_offloading_2c_38c77_sequential_loop_l4_exec_mode], section "llvm.metadata"
|
|
||||||
|
|
||||||
; The second argument of __kmpc_target_init and deinit is is set to true to indicate that we can run in SPMD mode.
|
|
||||||
; We also adjusted the global __omp_offloading_2c_38c77_sequential_loop_l4_exec_mode to have a zero initializer (which indicates SPMD mode to the runtime).
|
|
||||||
;.
|
|
||||||
; CHECK: @[[GLOB0:[0-9]+]] = private unnamed_addr constant [23 x i8] c"
|
|
||||||
; CHECK: @[[GLOB1:[0-9]+]] = private unnamed_addr constant [[STRUCT_IDENT_T:%.*]] { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @[[GLOB0]], i32 0, i32 0) }, align 8
|
|
||||||
; CHECK: @[[__OMP_OFFLOADING_2C_38C77_SEQUENTIAL_LOOP_L4_EXEC_MODE:[a-zA-Z0-9_$"\\.-]+]] = weak constant i8 0
|
|
||||||
; CHECK: @[[LLVM_COMPILER_USED:[a-zA-Z0-9_$"\\.-]+]] = appending global [1 x i8*] [i8* @__omp_offloading_2c_38c77_sequential_loop_l4_exec_mode], section "llvm.metadata"
|
|
||||||
;.
|
|
||||||
define weak void @__omp_offloading_2c_38c77_sequential_loop_l4() #0 {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@__omp_offloading_2c_38c77_sequential_loop_l4
|
|
||||||
; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
|
|
||||||
; CHECK-NEXT: [[DOTTHREADID_TEMP_:%.*]] = alloca i32, align 4
|
|
||||||
; CHECK-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = call i32 @__kmpc_target_init(%struct.ident_t* @[[GLOB1]], i1 true, i1 false, i1 true)
|
|
||||||
; CHECK-NEXT: [[EXEC_USER_CODE:%.*]] = icmp eq i32 [[TMP0]], -1
|
|
||||||
; CHECK-NEXT: br i1 [[EXEC_USER_CODE]], label [[USER_CODE_ENTRY:%.*]], label [[WORKER_EXIT:%.*]]
|
|
||||||
; CHECK: user_code.entry:
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @__kmpc_global_thread_num(%struct.ident_t* @[[GLOB1]]) #[[ATTR2:[0-9]+]]
|
|
||||||
; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTTHREADID_TEMP_]], align 4
|
|
||||||
; CHECK-NEXT: call void @__omp_outlined__(i32* noalias nocapture noundef nonnull readonly align 4 dereferenceable(4) [[DOTTHREADID_TEMP_]], i32* noalias nocapture noundef nonnull readnone align 4 dereferenceable(4) [[DOTZERO_ADDR]]) #[[ATTR2]]
|
|
||||||
; CHECK-NEXT: call void @__kmpc_target_deinit(%struct.ident_t* @[[GLOB1]], i1 true, i1 true)
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
; CHECK: worker.exit:
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
%.zero.addr = alloca i32, align 4
|
|
||||||
%.threadid_temp. = alloca i32, align 4
|
|
||||||
store i32 0, i32* %.zero.addr, align 4
|
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* @1, i1 false, i1 true, i1 true)
|
|
||||||
%exec_user_code = icmp eq i32 %0, -1
|
|
||||||
br i1 %exec_user_code, label %user_code.entry, label %worker.exit
|
|
||||||
|
|
||||||
user_code.entry: ; preds = %entry
|
|
||||||
%1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* @1)
|
|
||||||
store i32 %1, i32* %.threadid_temp., align 4
|
|
||||||
call void @__omp_outlined__(i32* %.threadid_temp., i32* %.zero.addr) #2
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* @1, i1 false, i1 true)
|
|
||||||
ret void
|
|
||||||
|
|
||||||
worker.exit: ; preds = %entry
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1)
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__(i32* noalias %.global_tid., i32* noalias %.bound_tid.) #0 {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__
|
|
||||||
; CHECK-SAME: (i32* noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree nonnull readnone align 4 dereferenceable(4) [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[CAPTURED_VARS_ADDRS:%.*]] = alloca [0 x i8*], align 8
|
|
||||||
; CHECK-NEXT: br label [[FOR_COND:%.*]]
|
|
||||||
; CHECK: for.cond:
|
|
||||||
; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_INC:%.*]] ]
|
|
||||||
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 100
|
|
||||||
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
|
||||||
; CHECK: for.body:
|
|
||||||
; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
|
|
||||||
; CHECK-NEXT: [[TMP1:%.*]] = bitcast [0 x i8*]* [[CAPTURED_VARS_ADDRS]] to i8**
|
|
||||||
; CHECK-NEXT: call void @__kmpc_parallel_51(%struct.ident_t* noundef @[[GLOB1]], i32 [[TMP0]], i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__1 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** noundef [[TMP1]], i64 noundef 0)
|
|
||||||
; CHECK-NEXT: br label [[FOR_INC]]
|
|
||||||
; CHECK: for.inc:
|
|
||||||
; CHECK-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
|
|
||||||
; CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP8:![0-9]+]]
|
|
||||||
; CHECK: for.end:
|
|
||||||
; CHECK-NEXT: call void @spmd_amenable()
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs = alloca [0 x i8*], align 8
|
|
||||||
br label %for.cond
|
|
||||||
|
|
||||||
for.cond: ; preds = %for.inc, %entry
|
|
||||||
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
||||||
%cmp = icmp slt i32 %i.0, 100
|
|
||||||
br i1 %cmp, label %for.body, label %for.end
|
|
||||||
|
|
||||||
for.body: ; preds = %for.cond
|
|
||||||
%0 = load i32, i32* %.global_tid., align 4
|
|
||||||
%1 = bitcast [0 x i8*]* %captured_vars_addrs to i8**
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* @1, i32 %0, i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__1 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__1_wrapper to i8*), i8** %1, i64 0)
|
|
||||||
br label %for.inc
|
|
||||||
|
|
||||||
for.inc: ; preds = %for.body
|
|
||||||
%inc = add nsw i32 %i.0, 1
|
|
||||||
br label %for.cond, !llvm.loop !6
|
|
||||||
|
|
||||||
for.end: ; preds = %for.cond
|
|
||||||
call void @spmd_amenable()
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__1(i32* noalias %.global_tid., i32* noalias %.bound_tid.) #0 {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__1
|
|
||||||
; CHECK-SAME: (i32* noalias nocapture nofree readnone [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone [[DOTBOUND_TID_:%.*]]) #[[ATTR0]] {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: call void @unknown() #[[ATTR4:[0-9]+]]
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
call void @unknown() #3
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent
|
|
||||||
declare void @unknown() #1
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__1_wrapper(i16 zeroext %0, i32 %1) #0 {
|
|
||||||
; CHECK-LABEL: define {{[^@]+}}@__omp_outlined__1_wrapper
|
|
||||||
; CHECK-SAME: (i16 zeroext [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR0]] {
|
|
||||||
; CHECK-NEXT: entry:
|
|
||||||
; CHECK-NEXT: [[DOTADDR1:%.*]] = alloca i32, align 4
|
|
||||||
; CHECK-NEXT: [[DOTZERO_ADDR:%.*]] = alloca i32, align 4
|
|
||||||
; CHECK-NEXT: [[GLOBAL_ARGS:%.*]] = alloca i8**, align 8
|
|
||||||
; CHECK-NEXT: store i32 0, i32* [[DOTZERO_ADDR]], align 4
|
|
||||||
; CHECK-NEXT: store i32 [[TMP1]], i32* [[DOTADDR1]], align 4
|
|
||||||
; CHECK-NEXT: call void @__kmpc_get_shared_variables(i8*** [[GLOBAL_ARGS]])
|
|
||||||
; CHECK-NEXT: call void @__omp_outlined__1(i32* [[DOTADDR1]], i32* [[DOTZERO_ADDR]]) #[[ATTR2]]
|
|
||||||
; CHECK-NEXT: ret void
|
|
||||||
;
|
|
||||||
entry:
|
|
||||||
%.addr1 = alloca i32, align 4
|
|
||||||
%.zero.addr = alloca i32, align 4
|
|
||||||
%global_args = alloca i8**, align 8
|
|
||||||
store i32 0, i32* %.zero.addr, align 4
|
|
||||||
store i32 %1, i32* %.addr1, align 4
|
|
||||||
call void @__kmpc_get_shared_variables(i8*** %global_args)
|
|
||||||
call void @__omp_outlined__1(i32* %.addr1, i32* %.zero.addr) #2
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @__kmpc_get_shared_variables(i8***)
|
|
||||||
|
|
||||||
declare void @__kmpc_parallel_51(%struct.ident_t*, i32, i32, i32, i32, i8*, i8*, i8**, i64)
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
|
||||||
declare i32 @__kmpc_global_thread_num(%struct.ident_t*) #2
|
|
||||||
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1)
|
|
||||||
|
|
||||||
declare void @spmd_amenable() #4
|
|
||||||
|
|
||||||
attributes #0 = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #2 = { nounwind }
|
|
||||||
attributes #3 = { convergent }
|
|
||||||
attributes #4 = { "llvm.assume"="ompx_spmd_amenable" }
|
|
||||||
|
|
||||||
!omp_offload.info = !{!0}
|
|
||||||
!nvvm.annotations = !{!1}
|
|
||||||
!llvm.module.flags = !{!2, !3, !4, !8, !9}
|
|
||||||
!llvm.ident = !{!5}
|
|
||||||
|
|
||||||
!0 = !{i32 0, i32 44, i32 232567, !"sequential_loop", i32 4, i32 0}
|
|
||||||
!1 = !{void ()* @__omp_offloading_2c_38c77_sequential_loop_l4, !"kernel", i32 1}
|
|
||||||
!2 = !{i32 1, !"wchar_size", i32 4}
|
|
||||||
!3 = !{i32 7, !"PIC Level", i32 2}
|
|
||||||
!4 = !{i32 7, !"frame-pointer", i32 2}
|
|
||||||
!5 = !{!"clang version 13.0.0"}
|
|
||||||
!6 = distinct !{!6, !7}
|
|
||||||
!7 = !{!"llvm.loop.mustprogress"}
|
|
||||||
!8 = !{i32 7, !"openmp", i32 50}
|
|
||||||
!9 = !{i32 7, !"openmp-device", i32 50}
|
|
||||||
;.
|
|
||||||
; CHECK: attributes #[[ATTR0]] = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
; CHECK: attributes #[[ATTR1:[0-9]+]] = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
; CHECK: attributes #[[ATTR2]] = { nounwind }
|
|
||||||
; CHECK: attributes #[[ATTR3:[0-9]+]] = { "llvm.assume"="ompx_spmd_amenable" }
|
|
||||||
; CHECK: attributes #[[ATTR4]] = { convergent }
|
|
||||||
;.
|
|
||||||
; CHECK: [[META0:![0-9]+]] = !{i32 0, i32 44, i32 232567, !"sequential_loop", i32 4, i32 0}
|
|
||||||
; CHECK: [[META1:![0-9]+]] = !{void ()* @__omp_offloading_2c_38c77_sequential_loop_l4, !"kernel", i32 1}
|
|
||||||
; CHECK: [[META2:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
|
|
||||||
; CHECK: [[META3:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
|
|
||||||
; CHECK: [[META4:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
|
|
||||||
; CHECK: [[META5:![0-9]+]] = !{i32 7, !"openmp", i32 50}
|
|
||||||
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
|
|
||||||
; CHECK: [[META7:![0-9]+]] = !{!"clang version 13.0.0"}
|
|
||||||
; CHECK: [[LOOP8]] = distinct !{!8, !9}
|
|
||||||
; CHECK: [[META9:![0-9]+]] = !{!"llvm.loop.mustprogress"}
|
|
||||||
;.
|
|
|
@ -1,233 +0,0 @@
|
||||||
; RUN: opt -passes=openmp-opt -pass-remarks=openmp-opt -pass-remarks-missed=openmp-opt -pass-remarks-analysis=openmp-opt -disable-output < %s 2>&1 | FileCheck %s
|
|
||||||
target triple = "nvptx64"
|
|
||||||
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:13:5: Kernel will be executed in generic-mode due to this potential side-effect, consider to add `__attribute__((assume("ompx_spmd_amenable"))` to the called function 'unknown'.
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:15:5: Kernel will be executed in generic-mode due to this potential side-effect, consider to add `__attribute__((assume("ompx_spmd_amenable"))` to the called function 'unknown'.
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:11:1: Generic-mode kernel is executed with a customized state machine that requires a fallback [1 known parallel regions, 2 unkown parallel regions] (bad).
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:13:5: State machine fallback caused by this call. If it is a false positive, use `__attribute__((assume("omp_no_openmp"))` (or "omp_no_parallelism").
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:15:5: State machine fallback caused by this call. If it is a false positive, use `__attribute__((assume("omp_no_openmp"))` (or "omp_no_parallelism").
|
|
||||||
; CHECK: remark: llvm/test/Transforms/OpenMP/spmdization_remarks.c:20:1: Generic-mode kernel is changed to SPMD-mode.
|
|
||||||
|
|
||||||
;; void unknown(void);
|
|
||||||
;; void known(void) {
|
|
||||||
;; #pragma omp parallel
|
|
||||||
;; {
|
|
||||||
;; unknown();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
;;
|
|
||||||
;; void test_fallback(void) {
|
|
||||||
;; #pragma omp target teams
|
|
||||||
;; {
|
|
||||||
;; unknown();
|
|
||||||
;; known();
|
|
||||||
;; unknown();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
;;
|
|
||||||
;; void no_openmp(void) __attribute__((assume("omp_no_openmp")));
|
|
||||||
;; void test_no_fallback(void) {
|
|
||||||
;; #pragma omp target teams
|
|
||||||
;; {
|
|
||||||
;; known();
|
|
||||||
;; known();
|
|
||||||
;; known();
|
|
||||||
;; spmd_amenable();
|
|
||||||
;; }
|
|
||||||
;; }
|
|
||||||
|
|
||||||
%struct.ident_t = type { i32, i32, i32, i32, i8* }
|
|
||||||
|
|
||||||
@0 = private unnamed_addr constant [103 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;__omp_offloading_2a_d80d3d_test_fallback_l11;11;1;;\00", align 1
|
|
||||||
@1 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([103 x i8], [103 x i8]* @0, i32 0, i32 0) }, align 8
|
|
||||||
@2 = private unnamed_addr constant [72 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;test_fallback;11;1;;\00", align 1
|
|
||||||
@3 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([72 x i8], [72 x i8]* @2, i32 0, i32 0) }, align 8
|
|
||||||
@4 = private unnamed_addr constant [104 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;__omp_offloading_2a_d80d3d_test_fallback_l11;11;25;;\00", align 1
|
|
||||||
@5 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([104 x i8], [104 x i8]* @4, i32 0, i32 0) }, align 8
|
|
||||||
@__omp_offloading_2a_d80d3d_test_fallback_l11_exec_mode = weak constant i8 1
|
|
||||||
@6 = private unnamed_addr constant [106 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;__omp_offloading_2a_d80d3d_test_no_fallback_l20;20;1;;\00", align 1
|
|
||||||
@7 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([106 x i8], [106 x i8]* @6, i32 0, i32 0) }, align 8
|
|
||||||
@8 = private unnamed_addr constant [75 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;test_no_fallback;20;1;;\00", align 1
|
|
||||||
@9 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([75 x i8], [75 x i8]* @8, i32 0, i32 0) }, align 8
|
|
||||||
@10 = private unnamed_addr constant [107 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;__omp_offloading_2a_d80d3d_test_no_fallback_l20;20;25;;\00", align 1
|
|
||||||
@11 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 0, i32 0, i8* getelementptr inbounds ([107 x i8], [107 x i8]* @10, i32 0, i32 0) }, align 8
|
|
||||||
@__omp_offloading_2a_d80d3d_test_no_fallback_l20_exec_mode = weak constant i8 1
|
|
||||||
@12 = private unnamed_addr constant [63 x i8] c";llvm/test/Transforms/OpenMP/spmdization_remarks.c;known;4;1;;\00", align 1
|
|
||||||
@13 = private unnamed_addr constant %struct.ident_t { i32 0, i32 2, i32 2, i32 0, i8* getelementptr inbounds ([63 x i8], [63 x i8]* @12, i32 0, i32 0) }, align 8
|
|
||||||
@G = external global i32
|
|
||||||
@llvm.compiler.used = appending global [2 x i8*] [i8* @__omp_offloading_2a_d80d3d_test_fallback_l11_exec_mode, i8* @__omp_offloading_2a_d80d3d_test_no_fallback_l20_exec_mode], section "llvm.metadata"
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define weak void @__omp_offloading_2a_d80d3d_test_fallback_l11() local_unnamed_addr #0 !dbg !15 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs.i.i = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @1, i1 false, i1 true, i1 true) #3, !dbg !18
|
|
||||||
%exec_user_code = icmp eq i32 %0, -1, !dbg !18
|
|
||||||
br i1 %exec_user_code, label %user_code.entry, label %common.ret, !dbg !18
|
|
||||||
|
|
||||||
common.ret: ; preds = %entry, %user_code.entry
|
|
||||||
ret void, !dbg !19
|
|
||||||
|
|
||||||
user_code.entry: ; preds = %entry
|
|
||||||
%1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @3) #3
|
|
||||||
call void @unknown() #6, !dbg !20
|
|
||||||
%2 = bitcast [0 x i8*]* %captured_vars_addrs.i.i to i8*
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
%4 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs.i.i, i64 0, i64 0, !dbg !23
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %3, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !23
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !26
|
|
||||||
call void @unknown() #6, !dbg !27
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* nonnull @5, i1 false, i1 true) #3, !dbg !28
|
|
||||||
br label %common.ret
|
|
||||||
}
|
|
||||||
|
|
||||||
declare i32 @__kmpc_target_init(%struct.ident_t*, i1, i1, i1) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: convergent
|
|
||||||
declare void @unknown() local_unnamed_addr #1
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
|
||||||
define hidden void @known() local_unnamed_addr #2 !dbg !29 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @13)
|
|
||||||
%1 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs, i64 0, i64 0, !dbg !30
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* nonnull @13, i32 %0, i32 1, i32 -1, i32 -1, i8* bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** nonnull %1, i64 0) #3, !dbg !30
|
|
||||||
ret void, !dbg !31
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: nounwind
|
|
||||||
declare i32 @__kmpc_global_thread_num(%struct.ident_t*) local_unnamed_addr #3
|
|
||||||
|
|
||||||
declare void @__kmpc_target_deinit(%struct.ident_t*, i1, i1) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: norecurse nounwind
|
|
||||||
define weak void @__omp_offloading_2a_d80d3d_test_no_fallback_l20() local_unnamed_addr #4 !dbg !32 {
|
|
||||||
entry:
|
|
||||||
%captured_vars_addrs.i2.i = alloca [0 x i8*], align 8
|
|
||||||
%0 = call i32 @__kmpc_target_init(%struct.ident_t* nonnull @7, i1 false, i1 true, i1 true) #3, !dbg !33
|
|
||||||
%exec_user_code = icmp eq i32 %0, -1, !dbg !33
|
|
||||||
br i1 %exec_user_code, label %user_code.entry, label %common.ret, !dbg !33
|
|
||||||
|
|
||||||
common.ret: ; preds = %entry, %user_code.entry
|
|
||||||
ret void, !dbg !34
|
|
||||||
|
|
||||||
user_code.entry: ; preds = %entry
|
|
||||||
%1 = call i32 @__kmpc_global_thread_num(%struct.ident_t* nonnull @9) #3
|
|
||||||
%2 = bitcast [0 x i8*]* %captured_vars_addrs.i2.i to i8*
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%3 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
%4 = getelementptr inbounds [0 x i8*], [0 x i8*]* %captured_vars_addrs.i2.i, i64 0, i64 0, !dbg !35
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %3, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !35
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !39
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%5 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %5, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !40
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !42
|
|
||||||
call void @llvm.lifetime.start.p0i8(i64 0, i8* nonnull %2) #3
|
|
||||||
%6 = call i32 @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @13) #3
|
|
||||||
call void @__kmpc_parallel_51(%struct.ident_t* noundef nonnull @13, i32 %6, i32 noundef 1, i32 noundef -1, i32 noundef -1, i8* noundef bitcast (void (i32*, i32*)* @__omp_outlined__2 to i8*), i8* noundef bitcast (void (i16, i32)* @__omp_outlined__2_wrapper to i8*), i8** noundef nonnull %4, i64 noundef 0) #3, !dbg !43
|
|
||||||
call void @llvm.lifetime.end.p0i8(i64 0, i8* nonnull %2) #3, !dbg !45
|
|
||||||
call void @spmd_amenable()
|
|
||||||
call void @__kmpc_target_deinit(%struct.ident_t* nonnull @11, i1 false, i1 true) #3, !dbg !46
|
|
||||||
br label %common.ret
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__2(i32* noalias nocapture nofree readnone %.global_tid., i32* noalias nocapture nofree readnone %.bound_tid.) #0 !dbg !47 {
|
|
||||||
entry:
|
|
||||||
call void @unknown() #6, !dbg !48
|
|
||||||
ret void, !dbg !49
|
|
||||||
}
|
|
||||||
|
|
||||||
; Function Attrs: convergent norecurse nounwind
|
|
||||||
define internal void @__omp_outlined__2_wrapper(i16 zeroext %0, i32 %1) #0 !dbg !50 {
|
|
||||||
entry:
|
|
||||||
%global_args = alloca i8**, align 8
|
|
||||||
call void @__kmpc_get_shared_variables(i8*** nonnull %global_args) #3, !dbg !51
|
|
||||||
call void @unknown() #6, !dbg !52
|
|
||||||
ret void, !dbg !51
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @__kmpc_get_shared_variables(i8***) local_unnamed_addr
|
|
||||||
|
|
||||||
declare void @__kmpc_parallel_51(%struct.ident_t*, i32, i32, i32, i32, i8*, i8*, i8**, i64) local_unnamed_addr
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #5
|
|
||||||
|
|
||||||
; Function Attrs: argmemonly nofree nosync nounwind willreturn
|
|
||||||
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #5
|
|
||||||
|
|
||||||
declare void @spmd_amenable() #7
|
|
||||||
|
|
||||||
attributes #0 = { convergent norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #1 = { convergent "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #2 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #3 = { nounwind }
|
|
||||||
attributes #4 = { norecurse nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="sm_53" "target-features"="+ptx32,+sm_53" }
|
|
||||||
attributes #5 = { argmemonly nofree nosync nounwind willreturn }
|
|
||||||
attributes #6 = { convergent nounwind }
|
|
||||||
attributes #7 = { "llvm.assume"="ompx_spmd_amenable" }
|
|
||||||
|
|
||||||
!llvm.dbg.cu = !{!0}
|
|
||||||
!omp_offload.info = !{!3, !4}
|
|
||||||
!nvvm.annotations = !{!5, !6}
|
|
||||||
!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13}
|
|
||||||
!llvm.ident = !{!14}
|
|
||||||
|
|
||||||
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: DebugDirectivesOnly, enums: !2, splitDebugInlining: false, nameTableKind: None)
|
|
||||||
!1 = !DIFile(filename: "spmdization_remarks.c", directory: "/data/src/llvm-project")
|
|
||||||
!2 = !{}
|
|
||||||
!3 = !{i32 0, i32 42, i32 14159165, !"test_no_fallback", i32 20, i32 1}
|
|
||||||
!4 = !{i32 0, i32 42, i32 14159165, !"test_fallback", i32 11, i32 0}
|
|
||||||
!5 = !{void ()* @__omp_offloading_2a_d80d3d_test_fallback_l11, !"kernel", i32 1}
|
|
||||||
!6 = !{void ()* @__omp_offloading_2a_d80d3d_test_no_fallback_l20, !"kernel", i32 1}
|
|
||||||
!7 = !{i32 7, !"Dwarf Version", i32 2}
|
|
||||||
!8 = !{i32 2, !"Debug Info Version", i32 3}
|
|
||||||
!9 = !{i32 1, !"wchar_size", i32 4}
|
|
||||||
!10 = !{i32 7, !"openmp", i32 50}
|
|
||||||
!11 = !{i32 7, !"openmp-device", i32 50}
|
|
||||||
!12 = !{i32 7, !"PIC Level", i32 2}
|
|
||||||
!13 = !{i32 7, !"frame-pointer", i32 2}
|
|
||||||
!14 = !{!"clang version 13.0.0"}
|
|
||||||
!15 = distinct !DISubprogram(name: "__omp_offloading_2a_d80d3d_test_fallback_l11", scope: !16, file: !16, line: 11, type: !17, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!16 = !DIFile(filename: "llvm/test/Transforms/OpenMP/spmdization_remarks.c", directory: "/data/src/llvm-project")
|
|
||||||
!17 = !DISubroutineType(types: !2)
|
|
||||||
!18 = !DILocation(line: 11, column: 1, scope: !15)
|
|
||||||
!19 = !DILocation(line: 0, scope: !15)
|
|
||||||
!20 = !DILocation(line: 13, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!21 = distinct !DISubprogram(name: "__omp_outlined__", scope: !16, file: !16, line: 11, type: !17, scopeLine: 11, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!22 = distinct !DILocation(line: 11, column: 1, scope: !15)
|
|
||||||
!23 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !25)
|
|
||||||
!24 = distinct !DISubprogram(name: "known", scope: !16, file: !16, line: 3, type: !17, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!25 = distinct !DILocation(line: 14, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!26 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !25)
|
|
||||||
!27 = !DILocation(line: 15, column: 5, scope: !21, inlinedAt: !22)
|
|
||||||
!28 = !DILocation(line: 11, column: 25, scope: !15)
|
|
||||||
!29 = distinct !DISubprogram(name: "known", scope: !16, file: !16, line: 3, type: !17, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!30 = !DILocation(line: 4, column: 1, scope: !29)
|
|
||||||
!31 = !DILocation(line: 8, column: 1, scope: !29)
|
|
||||||
!32 = distinct !DISubprogram(name: "__omp_offloading_2a_d80d3d_test_no_fallback_l20", scope: !16, file: !16, line: 20, type: !17, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!33 = !DILocation(line: 20, column: 1, scope: !32)
|
|
||||||
!34 = !DILocation(line: 0, scope: !32)
|
|
||||||
!35 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !36)
|
|
||||||
!36 = distinct !DILocation(line: 22, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!37 = distinct !DISubprogram(name: "__omp_outlined__1", scope: !16, file: !16, line: 20, type: !17, scopeLine: 20, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!38 = distinct !DILocation(line: 20, column: 1, scope: !32)
|
|
||||||
!39 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !36)
|
|
||||||
!40 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !41)
|
|
||||||
!41 = distinct !DILocation(line: 23, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!42 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !41)
|
|
||||||
!43 = !DILocation(line: 4, column: 1, scope: !24, inlinedAt: !44)
|
|
||||||
!44 = distinct !DILocation(line: 24, column: 5, scope: !37, inlinedAt: !38)
|
|
||||||
!45 = !DILocation(line: 8, column: 1, scope: !24, inlinedAt: !44)
|
|
||||||
!46 = !DILocation(line: 20, column: 25, scope: !32)
|
|
||||||
!47 = distinct !DISubprogram(name: "__omp_outlined__2", scope: !16, file: !16, line: 4, type: !17, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!48 = !DILocation(line: 6, column: 5, scope: !47)
|
|
||||||
!49 = !DILocation(line: 7, column: 3, scope: !47)
|
|
||||||
!50 = distinct !DISubprogram(linkageName: "__omp_outlined__2_wrapper", scope: !16, file: !16, line: 4, type: !17, scopeLine: 4, flags: DIFlagArtificial, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
|
||||||
!51 = !DILocation(line: 4, column: 1, scope: !50)
|
|
||||||
!52 = !DILocation(line: 6, column: 5, scope: !47, inlinedAt: !53)
|
|
||||||
!53 = distinct !DILocation(line: 4, column: 1, scope: !50)
|
|
|
@ -1,94 +0,0 @@
|
||||||
//===-- target.h ---------- OpenMP device runtime target implementation ---===//
|
|
||||||
//
|
|
||||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
||||||
// See https://llvm.org/LICENSE.txt for license information.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
//
|
|
||||||
// Target region interfaces are simple interfaces designed to allow middle-end
|
|
||||||
// (=LLVM) passes to analyze and transform the code. To achieve good performance
|
|
||||||
// it may be required to run the associated passes. However, implementations of
|
|
||||||
// this interface shall always provide a correct implementation as close to the
|
|
||||||
// user expected code as possible.
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#ifndef LLVM_OPENMP_LIBOMPTARGET_DEVICERTLS_COMMON_TARGET_H
|
|
||||||
#define LLVM_OPENMP_LIBOMPTARGET_DEVICERTLS_COMMON_TARGET_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
|
|
||||||
/// Forward declaration of the source location identifier "ident".
|
|
||||||
typedef struct ident ident_t;
|
|
||||||
|
|
||||||
/// The target region _kernel_ interface for GPUs
|
|
||||||
///
|
|
||||||
/// This deliberatly simple interface provides the middle-end (=LLVM) with
|
|
||||||
/// easier means to reason about the semantic of the code and transform it as
|
|
||||||
/// well. The runtime calls are therefore also desiged to carry sufficient
|
|
||||||
/// information necessary for optimizations.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// Intended usage:
|
|
||||||
///
|
|
||||||
/// \code
|
|
||||||
/// void kernel(...) {
|
|
||||||
/// ThreadKind = __kmpc_target_init(Ident, /* IsSPMD */ false,
|
|
||||||
/// /* UseGenericStateMachine */ true,
|
|
||||||
/// /* RequiresFullRuntime */ ... );
|
|
||||||
/// if (ThreadKind == -1) {
|
|
||||||
/// // User defined kernel code.
|
|
||||||
/// }
|
|
||||||
/// __kmpc_target_deinit(...);
|
|
||||||
/// }
|
|
||||||
/// \endcode
|
|
||||||
///
|
|
||||||
/// Which can be transformed to:
|
|
||||||
///
|
|
||||||
/// \code
|
|
||||||
/// void kernel(...) {
|
|
||||||
/// ThreadKind = __kmpc_target_init(Ident, /* IsSPMD */ false,
|
|
||||||
/// /* UseGenericStateMachine */ false,
|
|
||||||
/// /* RequiresFullRuntime */ ... );
|
|
||||||
/// if (ThreadKind == -1) {
|
|
||||||
/// // User defined kernel code.
|
|
||||||
/// } else {
|
|
||||||
/// assume(ThreadKind == ThreadId);
|
|
||||||
/// // Custom, kernel-specific state machine code.
|
|
||||||
/// }
|
|
||||||
/// __kmpc_target_deinit(...);
|
|
||||||
/// }
|
|
||||||
/// \endcode
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///{
|
|
||||||
|
|
||||||
/// Initialization
|
|
||||||
///
|
|
||||||
/// Must be called by all threads.
|
|
||||||
///
|
|
||||||
/// \param Ident Source location identification, can be NULL.
|
|
||||||
///
|
|
||||||
int32_t __kmpc_target_init(ident_t *Ident, bool IsSPMD,
|
|
||||||
bool UseGenericStateMachine,
|
|
||||||
bool RequiresFullRuntime);
|
|
||||||
|
|
||||||
/// De-Initialization
|
|
||||||
///
|
|
||||||
/// Must be called by the main thread in generic mode, can be called by all
|
|
||||||
/// threads. Must be called by all threads in SPMD mode.
|
|
||||||
///
|
|
||||||
/// In non-SPMD, this function releases the workers trapped in a state machine
|
|
||||||
/// and also any memory dynamically allocated by the runtime.
|
|
||||||
///
|
|
||||||
/// \param Ident Source location identification, can be NULL.
|
|
||||||
///
|
|
||||||
void __kmpc_target_deinit(ident_t *Ident, bool IsSPMD,
|
|
||||||
bool RequiresFullRuntime);
|
|
||||||
|
|
||||||
///}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -204,15 +204,15 @@ public:
|
||||||
INLINE static void dispatch_init(kmp_Ident *loc, int32_t threadId,
|
INLINE static void dispatch_init(kmp_Ident *loc, int32_t threadId,
|
||||||
kmp_sched_t schedule, T lb, T ub, ST st,
|
kmp_sched_t schedule, T lb, T ub, ST st,
|
||||||
ST chunk) {
|
ST chunk) {
|
||||||
if (isRuntimeUninitialized()) {
|
if (checkRuntimeUninitialized(loc)) {
|
||||||
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
||||||
// may appear only in L2 parallel regions with lightweight runtime.
|
// may appear only in L2 parallel regions with lightweight runtime.
|
||||||
ASSERT0(LT_FUSSY, __kmpc_is_spmd_exec_mode(), "Expected non-SPMD mode.");
|
ASSERT0(LT_FUSSY, checkSPMDMode(loc), "Expected non-SPMD mode.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_TaskDescr *currTaskDescr = getMyTopTaskDescriptor(tid);
|
omptarget_nvptx_TaskDescr *currTaskDescr = getMyTopTaskDescriptor(tid);
|
||||||
T tnum = GetNumberOfOmpThreads(__kmpc_is_spmd_exec_mode());
|
T tnum = GetNumberOfOmpThreads(checkSPMDMode(loc));
|
||||||
T tripCount = ub - lb + 1; // +1 because ub is inclusive
|
T tripCount = ub - lb + 1; // +1 because ub is inclusive
|
||||||
ASSERT0(LT_FUSSY, threadId < tnum,
|
ASSERT0(LT_FUSSY, threadId < tnum,
|
||||||
"current thread is not needed here; error");
|
"current thread is not needed here; error");
|
||||||
|
@ -441,10 +441,10 @@ public:
|
||||||
|
|
||||||
INLINE static int dispatch_next(kmp_Ident *loc, int32_t gtid, int32_t *plast,
|
INLINE static int dispatch_next(kmp_Ident *loc, int32_t gtid, int32_t *plast,
|
||||||
T *plower, T *pupper, ST *pstride) {
|
T *plower, T *pupper, ST *pstride) {
|
||||||
if (isRuntimeUninitialized()) {
|
if (checkRuntimeUninitialized(loc)) {
|
||||||
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
// In SPMD mode no need to check parallelism level - dynamic scheduling
|
||||||
// may appear only in L2 parallel regions with lightweight runtime.
|
// may appear only in L2 parallel regions with lightweight runtime.
|
||||||
ASSERT0(LT_FUSSY, __kmpc_is_spmd_exec_mode(), "Expected non-SPMD mode.");
|
ASSERT0(LT_FUSSY, checkSPMDMode(loc), "Expected non-SPMD mode.");
|
||||||
if (*plast)
|
if (*plast)
|
||||||
return DISPATCH_FINISHED;
|
return DISPATCH_FINISHED;
|
||||||
*plast = 1;
|
*plast = 1;
|
||||||
|
@ -453,8 +453,8 @@ public:
|
||||||
// ID of a thread in its own warp
|
// ID of a thread in its own warp
|
||||||
|
|
||||||
// automatically selects thread or warp ID based on selected implementation
|
// automatically selects thread or warp ID based on selected implementation
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
ASSERT0(LT_FUSSY, gtid < GetNumberOfOmpThreads(__kmpc_is_spmd_exec_mode()),
|
ASSERT0(LT_FUSSY, gtid < GetNumberOfOmpThreads(checkSPMDMode(loc)),
|
||||||
"current thread is not needed here; error");
|
"current thread is not needed here; error");
|
||||||
// retrieve schedule
|
// retrieve schedule
|
||||||
kmp_sched_t schedule =
|
kmp_sched_t schedule =
|
||||||
|
@ -624,7 +624,7 @@ EXTERN void __kmpc_for_static_init_4(kmp_Ident *loc, int32_t global_tid,
|
||||||
PRINT0(LD_IO, "call kmpc_for_static_init_4\n");
|
PRINT0(LD_IO, "call kmpc_for_static_init_4\n");
|
||||||
omptarget_nvptx_LoopSupport<int32_t, int32_t>::for_static_init(
|
omptarget_nvptx_LoopSupport<int32_t, int32_t>::for_static_init(
|
||||||
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
||||||
__kmpc_is_spmd_exec_mode());
|
checkSPMDMode(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN void __kmpc_for_static_init_4u(kmp_Ident *loc, int32_t global_tid,
|
EXTERN void __kmpc_for_static_init_4u(kmp_Ident *loc, int32_t global_tid,
|
||||||
|
@ -635,7 +635,7 @@ EXTERN void __kmpc_for_static_init_4u(kmp_Ident *loc, int32_t global_tid,
|
||||||
PRINT0(LD_IO, "call kmpc_for_static_init_4u\n");
|
PRINT0(LD_IO, "call kmpc_for_static_init_4u\n");
|
||||||
omptarget_nvptx_LoopSupport<uint32_t, int32_t>::for_static_init(
|
omptarget_nvptx_LoopSupport<uint32_t, int32_t>::for_static_init(
|
||||||
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
||||||
__kmpc_is_spmd_exec_mode());
|
checkSPMDMode(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN void __kmpc_for_static_init_8(kmp_Ident *loc, int32_t global_tid,
|
EXTERN void __kmpc_for_static_init_8(kmp_Ident *loc, int32_t global_tid,
|
||||||
|
@ -646,7 +646,7 @@ EXTERN void __kmpc_for_static_init_8(kmp_Ident *loc, int32_t global_tid,
|
||||||
PRINT0(LD_IO, "call kmpc_for_static_init_8\n");
|
PRINT0(LD_IO, "call kmpc_for_static_init_8\n");
|
||||||
omptarget_nvptx_LoopSupport<int64_t, int64_t>::for_static_init(
|
omptarget_nvptx_LoopSupport<int64_t, int64_t>::for_static_init(
|
||||||
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
||||||
__kmpc_is_spmd_exec_mode());
|
checkSPMDMode(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN void __kmpc_for_static_init_8u(kmp_Ident *loc, int32_t global_tid,
|
EXTERN void __kmpc_for_static_init_8u(kmp_Ident *loc, int32_t global_tid,
|
||||||
|
@ -657,7 +657,7 @@ EXTERN void __kmpc_for_static_init_8u(kmp_Ident *loc, int32_t global_tid,
|
||||||
PRINT0(LD_IO, "call kmpc_for_static_init_8u\n");
|
PRINT0(LD_IO, "call kmpc_for_static_init_8u\n");
|
||||||
omptarget_nvptx_LoopSupport<uint64_t, int64_t>::for_static_init(
|
omptarget_nvptx_LoopSupport<uint64_t, int64_t>::for_static_init(
|
||||||
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
global_tid, schedtype, plastiter, plower, pupper, pstride, chunk,
|
||||||
__kmpc_is_spmd_exec_mode());
|
checkSPMDMode(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN
|
EXTERN
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#pragma omp declare target
|
#pragma omp declare target
|
||||||
|
|
||||||
#include "common/omptarget.h"
|
#include "common/omptarget.h"
|
||||||
#include "common/support.h"
|
|
||||||
#include "target_impl.h"
|
#include "target_impl.h"
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -27,18 +26,16 @@ extern omptarget_nvptx_Queue<omptarget_nvptx_ThreadPrivateContext,
|
||||||
// init entry points
|
// init entry points
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static void __kmpc_generic_kernel_init() {
|
EXTERN void __kmpc_kernel_init(int ThreadLimit, int16_t RequiresOMPRuntime) {
|
||||||
PRINT(LD_IO, "call to __kmpc_kernel_init with version %f\n",
|
PRINT(LD_IO, "call to __kmpc_kernel_init with version %f\n",
|
||||||
OMPTARGET_NVPTX_VERSION);
|
OMPTARGET_NVPTX_VERSION);
|
||||||
|
ASSERT0(LT_FUSSY, RequiresOMPRuntime,
|
||||||
if (GetLaneId() == 0)
|
"Generic always requires initialized runtime.");
|
||||||
parallelLevel[GetWarpId()] = 0;
|
setExecutionParameters(Generic, RuntimeInitialized);
|
||||||
|
for (int I = 0; I < MAX_THREADS_PER_TEAM / WARPSIZE; ++I)
|
||||||
|
parallelLevel[I] = 0;
|
||||||
|
|
||||||
int threadIdInBlock = GetThreadIdInBlock();
|
int threadIdInBlock = GetThreadIdInBlock();
|
||||||
if (threadIdInBlock != GetMasterThreadID())
|
|
||||||
return;
|
|
||||||
|
|
||||||
setExecutionParameters(Generic, RuntimeInitialized);
|
|
||||||
ASSERT0(LT_FUSSY, threadIdInBlock == GetMasterThreadID(),
|
ASSERT0(LT_FUSSY, threadIdInBlock == GetMasterThreadID(),
|
||||||
"__kmpc_kernel_init() must be called by team master warp only!");
|
"__kmpc_kernel_init() must be called by team master warp only!");
|
||||||
PRINT0(LD_IO, "call to __kmpc_kernel_init for master\n");
|
PRINT0(LD_IO, "call to __kmpc_kernel_init for master\n");
|
||||||
|
@ -50,7 +47,7 @@ static void __kmpc_generic_kernel_init() {
|
||||||
omptarget_nvptx_device_State[slot].Dequeue();
|
omptarget_nvptx_device_State[slot].Dequeue();
|
||||||
|
|
||||||
// init thread private
|
// init thread private
|
||||||
int threadId = 0;
|
int threadId = GetLogicalThreadIdInBlock(/*isSPMDExecutionMode=*/false);
|
||||||
omptarget_nvptx_threadPrivateContext->InitThreadPrivateContext(threadId);
|
omptarget_nvptx_threadPrivateContext->InitThreadPrivateContext(threadId);
|
||||||
|
|
||||||
// init team context
|
// init team context
|
||||||
|
@ -65,17 +62,20 @@ static void __kmpc_generic_kernel_init() {
|
||||||
// set number of threads and thread limit in team to started value
|
// set number of threads and thread limit in team to started value
|
||||||
omptarget_nvptx_TaskDescr *currTaskDescr =
|
omptarget_nvptx_TaskDescr *currTaskDescr =
|
||||||
omptarget_nvptx_threadPrivateContext->GetTopLevelTaskDescr(threadId);
|
omptarget_nvptx_threadPrivateContext->GetTopLevelTaskDescr(threadId);
|
||||||
nThreads = GetNumberOfWorkersInTeam();
|
nThreads = GetNumberOfThreadsInBlock();
|
||||||
threadLimit = nThreads;
|
threadLimit = ThreadLimit;
|
||||||
|
|
||||||
omptarget_nvptx_globalArgs.Init();
|
if (!__kmpc_is_spmd_exec_mode())
|
||||||
|
omptarget_nvptx_globalArgs.Init();
|
||||||
|
|
||||||
__kmpc_data_sharing_init_stack();
|
__kmpc_data_sharing_init_stack();
|
||||||
__kmpc_impl_target_init();
|
__kmpc_impl_target_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __kmpc_generic_kernel_deinit() {
|
EXTERN void __kmpc_kernel_deinit(int16_t IsOMPRuntimeInitialized) {
|
||||||
PRINT0(LD_IO, "call to __kmpc_kernel_deinit\n");
|
PRINT0(LD_IO, "call to __kmpc_kernel_deinit\n");
|
||||||
|
ASSERT0(LT_FUSSY, IsOMPRuntimeInitialized,
|
||||||
|
"Generic always requires initialized runtime.");
|
||||||
// Enqueue omp state object for use by another team.
|
// Enqueue omp state object for use by another team.
|
||||||
int slot = usedSlotIdx;
|
int slot = usedSlotIdx;
|
||||||
omptarget_nvptx_device_State[slot].Enqueue(
|
omptarget_nvptx_device_State[slot].Enqueue(
|
||||||
|
@ -84,11 +84,12 @@ static void __kmpc_generic_kernel_deinit() {
|
||||||
omptarget_nvptx_workFn = 0;
|
omptarget_nvptx_workFn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __kmpc_spmd_kernel_init(bool RequiresFullRuntime) {
|
EXTERN void __kmpc_spmd_kernel_init(int ThreadLimit,
|
||||||
|
int16_t RequiresOMPRuntime) {
|
||||||
PRINT0(LD_IO, "call to __kmpc_spmd_kernel_init\n");
|
PRINT0(LD_IO, "call to __kmpc_spmd_kernel_init\n");
|
||||||
|
|
||||||
setExecutionParameters(Spmd, RequiresFullRuntime ? RuntimeInitialized
|
setExecutionParameters(Spmd, RequiresOMPRuntime ? RuntimeInitialized
|
||||||
: RuntimeUninitialized);
|
: RuntimeUninitialized);
|
||||||
int threadId = GetThreadIdInBlock();
|
int threadId = GetThreadIdInBlock();
|
||||||
if (threadId == 0) {
|
if (threadId == 0) {
|
||||||
usedSlotIdx = __kmpc_impl_smid() % MAX_SM;
|
usedSlotIdx = __kmpc_impl_smid() % MAX_SM;
|
||||||
|
@ -99,8 +100,11 @@ static void __kmpc_spmd_kernel_init(bool RequiresFullRuntime) {
|
||||||
1 + (GetNumberOfThreadsInBlock() > 1 ? OMP_ACTIVE_PARALLEL_LEVEL : 0);
|
1 + (GetNumberOfThreadsInBlock() > 1 ? OMP_ACTIVE_PARALLEL_LEVEL : 0);
|
||||||
}
|
}
|
||||||
__kmpc_data_sharing_init_stack();
|
__kmpc_data_sharing_init_stack();
|
||||||
if (!RequiresFullRuntime)
|
if (!RequiresOMPRuntime) {
|
||||||
|
// Runtime is not required - exit.
|
||||||
|
__kmpc_impl_syncthreads();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Team Context Initialization.
|
// Team Context Initialization.
|
||||||
|
@ -134,17 +138,16 @@ static void __kmpc_spmd_kernel_init(bool RequiresFullRuntime) {
|
||||||
newTaskDescr);
|
newTaskDescr);
|
||||||
|
|
||||||
// init thread private from init value
|
// init thread private from init value
|
||||||
int ThreadLimit = GetNumberOfProcsInTeam(/* IsSPMD */ true);
|
|
||||||
PRINT(LD_PAR,
|
PRINT(LD_PAR,
|
||||||
"thread will execute parallel region with id %d in a team of "
|
"thread will execute parallel region with id %d in a team of "
|
||||||
"%d threads\n",
|
"%d threads\n",
|
||||||
(int)newTaskDescr->ThreadId(), (int)ThreadLimit);
|
(int)newTaskDescr->ThreadId(), (int)ThreadLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __kmpc_spmd_kernel_deinit(bool RequiresFullRuntime) {
|
EXTERN void __kmpc_spmd_kernel_deinit_v2(int16_t RequiresOMPRuntime) {
|
||||||
// We're not going to pop the task descr stack of each thread since
|
// We're not going to pop the task descr stack of each thread since
|
||||||
// there are no more parallel regions in SPMD mode.
|
// there are no more parallel regions in SPMD mode.
|
||||||
if (!RequiresFullRuntime)
|
if (!RequiresOMPRuntime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
__kmpc_impl_syncthreads();
|
__kmpc_impl_syncthreads();
|
||||||
|
@ -162,68 +165,4 @@ EXTERN int8_t __kmpc_is_spmd_exec_mode() {
|
||||||
return (execution_param & ModeMask) == Spmd;
|
return (execution_param & ModeMask) == Spmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN bool __kmpc_kernel_parallel(void**WorkFn);
|
|
||||||
|
|
||||||
static void __kmpc_target_region_state_machine(ident_t *Ident) {
|
|
||||||
|
|
||||||
int TId = GetThreadIdInBlock();
|
|
||||||
do {
|
|
||||||
void* WorkFn = 0;
|
|
||||||
|
|
||||||
// Wait for the signal that we have a new work function.
|
|
||||||
__kmpc_barrier_simple_spmd(Ident, TId);
|
|
||||||
|
|
||||||
|
|
||||||
// Retrieve the work function from the runtime.
|
|
||||||
bool IsActive = __kmpc_kernel_parallel(&WorkFn);
|
|
||||||
|
|
||||||
// If there is nothing more to do, break out of the state machine by
|
|
||||||
// returning to the caller.
|
|
||||||
if (!WorkFn)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (IsActive) {
|
|
||||||
((void(*)(uint32_t,uint32_t))WorkFn)(0, TId);
|
|
||||||
__kmpc_kernel_end_parallel();
|
|
||||||
}
|
|
||||||
|
|
||||||
__kmpc_barrier_simple_spmd(Ident, TId);
|
|
||||||
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
EXTERN
|
|
||||||
int32_t __kmpc_target_init(ident_t *Ident, bool IsSPMD,
|
|
||||||
bool UseGenericStateMachine,
|
|
||||||
bool RequiresFullRuntime) {
|
|
||||||
int TId = GetThreadIdInBlock();
|
|
||||||
if (IsSPMD)
|
|
||||||
__kmpc_spmd_kernel_init(RequiresFullRuntime);
|
|
||||||
else
|
|
||||||
__kmpc_generic_kernel_init();
|
|
||||||
|
|
||||||
if (IsSPMD) {
|
|
||||||
__kmpc_barrier_simple_spmd(Ident, TId);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TId == GetMasterThreadID())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (UseGenericStateMachine)
|
|
||||||
__kmpc_target_region_state_machine(Ident);
|
|
||||||
|
|
||||||
return TId;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXTERN
|
|
||||||
void __kmpc_target_deinit(ident_t *Ident, bool IsSPMD,
|
|
||||||
bool RequiresFullRuntime) {
|
|
||||||
if (IsSPMD)
|
|
||||||
__kmpc_spmd_kernel_deinit(RequiresFullRuntime);
|
|
||||||
else
|
|
||||||
__kmpc_generic_kernel_deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma omp end declare target
|
#pragma omp end declare target
|
||||||
|
|
|
@ -181,14 +181,14 @@ EXTERN void __kmpc_serialized_parallel(kmp_Ident *loc, uint32_t global_tid) {
|
||||||
|
|
||||||
IncParallelLevel(/*ActiveParallel=*/false, __kmpc_impl_activemask());
|
IncParallelLevel(/*ActiveParallel=*/false, __kmpc_impl_activemask());
|
||||||
|
|
||||||
if (isRuntimeUninitialized()) {
|
if (checkRuntimeUninitialized(loc)) {
|
||||||
ASSERT0(LT_FUSSY, __kmpc_is_spmd_exec_mode(),
|
ASSERT0(LT_FUSSY, checkSPMDMode(loc),
|
||||||
"Expected SPMD mode with uninitialized runtime.");
|
"Expected SPMD mode with uninitialized runtime.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume this is only called for nested parallel
|
// assume this is only called for nested parallel
|
||||||
int threadId = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int threadId = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
|
|
||||||
// unlike actual parallel, threads in the same team do not share
|
// unlike actual parallel, threads in the same team do not share
|
||||||
// the workTaskDescr in this case and num threads is fixed to 1
|
// the workTaskDescr in this case and num threads is fixed to 1
|
||||||
|
@ -220,14 +220,14 @@ EXTERN void __kmpc_end_serialized_parallel(kmp_Ident *loc,
|
||||||
|
|
||||||
DecParallelLevel(/*ActiveParallel=*/false, __kmpc_impl_activemask());
|
DecParallelLevel(/*ActiveParallel=*/false, __kmpc_impl_activemask());
|
||||||
|
|
||||||
if (isRuntimeUninitialized()) {
|
if (checkRuntimeUninitialized(loc)) {
|
||||||
ASSERT0(LT_FUSSY, __kmpc_is_spmd_exec_mode(),
|
ASSERT0(LT_FUSSY, checkSPMDMode(loc),
|
||||||
"Expected SPMD mode with uninitialized runtime.");
|
"Expected SPMD mode with uninitialized runtime.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop stack
|
// pop stack
|
||||||
int threadId = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int threadId = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_TaskDescr *currTaskDescr = getMyTopTaskDescriptor(threadId);
|
omptarget_nvptx_TaskDescr *currTaskDescr = getMyTopTaskDescriptor(threadId);
|
||||||
// set new top
|
// set new top
|
||||||
omptarget_nvptx_threadPrivateContext->SetTopLevelTaskDescr(
|
omptarget_nvptx_threadPrivateContext->SetTopLevelTaskDescr(
|
||||||
|
@ -249,8 +249,8 @@ EXTERN uint16_t __kmpc_parallel_level(kmp_Ident *loc, uint32_t global_tid) {
|
||||||
// it's cheap to recalculate this value so we never use the result
|
// it's cheap to recalculate this value so we never use the result
|
||||||
// of this call.
|
// of this call.
|
||||||
EXTERN int32_t __kmpc_global_thread_num(kmp_Ident *loc) {
|
EXTERN int32_t __kmpc_global_thread_num(kmp_Ident *loc) {
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
return GetOmpThreadId(tid, __kmpc_is_spmd_exec_mode());
|
return GetOmpThreadId(tid, checkSPMDMode(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -260,9 +260,9 @@ EXTERN int32_t __kmpc_global_thread_num(kmp_Ident *loc) {
|
||||||
EXTERN void __kmpc_push_num_threads(kmp_Ident *loc, int32_t tid,
|
EXTERN void __kmpc_push_num_threads(kmp_Ident *loc, int32_t tid,
|
||||||
int32_t num_threads) {
|
int32_t num_threads) {
|
||||||
PRINT(LD_IO, "call kmpc_push_num_threads %d\n", num_threads);
|
PRINT(LD_IO, "call kmpc_push_num_threads %d\n", num_threads);
|
||||||
ASSERT0(LT_FUSSY, isRuntimeInitialized(),
|
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||||
"Runtime must be initialized.");
|
"Runtime must be initialized.");
|
||||||
tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_threadPrivateContext->NumThreadsForNextParallel(tid) =
|
omptarget_nvptx_threadPrivateContext->NumThreadsForNextParallel(tid) =
|
||||||
num_threads;
|
num_threads;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ EXTERN void __kmpc_parallel_51(kmp_Ident *ident, kmp_int32 global_tid,
|
||||||
(1 + (IsActiveParallelRegion ? OMP_ACTIVE_PARALLEL_LEVEL : 0));
|
(1 + (IsActiveParallelRegion ? OMP_ACTIVE_PARALLEL_LEVEL : 0));
|
||||||
|
|
||||||
// Master signals work to activate workers.
|
// Master signals work to activate workers.
|
||||||
__kmpc_barrier_simple_spmd(ident, 0);
|
__kmpc_barrier_simple_spmd(nullptr, 0);
|
||||||
|
|
||||||
// OpenMP [2.5, Parallel Construct, p.49]
|
// OpenMP [2.5, Parallel Construct, p.49]
|
||||||
// There is an implied barrier at the end of a parallel region. After the
|
// There is an implied barrier at the end of a parallel region. After the
|
||||||
|
@ -339,7 +339,7 @@ EXTERN void __kmpc_parallel_51(kmp_Ident *ident, kmp_int32 global_tid,
|
||||||
// execution of the enclosing task region.
|
// execution of the enclosing task region.
|
||||||
//
|
//
|
||||||
// The master waits at this barrier until all workers are done.
|
// The master waits at this barrier until all workers are done.
|
||||||
__kmpc_barrier_simple_spmd(ident, 0);
|
__kmpc_barrier_simple_spmd(nullptr, 0);
|
||||||
|
|
||||||
// Decrement parallel level for non-SPMD warps.
|
// Decrement parallel level for non-SPMD warps.
|
||||||
for (int I = 0; I < NumWarps; ++I)
|
for (int I = 0; I < NumWarps; ++I)
|
||||||
|
|
|
@ -159,11 +159,11 @@ int32_t __kmpc_nvptx_parallel_reduce_nowait_v2(
|
||||||
kmp_InterWarpCopyFctPtr cpyFct) {
|
kmp_InterWarpCopyFctPtr cpyFct) {
|
||||||
return nvptx_parallel_reduce_nowait(
|
return nvptx_parallel_reduce_nowait(
|
||||||
global_tid, num_vars, reduce_size, reduce_data, shflFct, cpyFct,
|
global_tid, num_vars, reduce_size, reduce_data, shflFct, cpyFct,
|
||||||
__kmpc_is_spmd_exec_mode(), isRuntimeUninitialized());
|
checkSPMDMode(loc), checkRuntimeUninitialized(loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE static bool isMaster(kmp_Ident *loc, uint32_t ThreadId) {
|
INLINE static bool isMaster(kmp_Ident *loc, uint32_t ThreadId) {
|
||||||
return !__kmpc_is_spmd_exec_mode() || IsTeamMaster(ThreadId);
|
return checkGenericMode(loc) || IsTeamMaster(ThreadId);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE static uint32_t roundToWarpsize(uint32_t s) {
|
INLINE static uint32_t roundToWarpsize(uint32_t s) {
|
||||||
|
@ -184,16 +184,16 @@ EXTERN int32_t __kmpc_nvptx_teams_reduce_nowait_v2(
|
||||||
kmp_ListGlobalFctPtr glredFct) {
|
kmp_ListGlobalFctPtr glredFct) {
|
||||||
|
|
||||||
// Terminate all threads in non-SPMD mode except for the master thread.
|
// Terminate all threads in non-SPMD mode except for the master thread.
|
||||||
if (!__kmpc_is_spmd_exec_mode() && GetThreadIdInBlock() != GetMasterThreadID())
|
if (checkGenericMode(loc) && GetThreadIdInBlock() != GetMasterThreadID())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
uint32_t ThreadId = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
uint32_t ThreadId = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
|
|
||||||
// In non-generic mode all workers participate in the teams reduction.
|
// In non-generic mode all workers participate in the teams reduction.
|
||||||
// In generic mode only the team master participates in the teams
|
// In generic mode only the team master participates in the teams
|
||||||
// reduction because the workers are waiting for parallel work.
|
// reduction because the workers are waiting for parallel work.
|
||||||
uint32_t NumThreads =
|
uint32_t NumThreads =
|
||||||
__kmpc_is_spmd_exec_mode() ? GetNumberOfOmpThreads(/*isSPMDExecutionMode=*/true)
|
checkSPMDMode(loc) ? GetNumberOfOmpThreads(/*isSPMDExecutionMode=*/true)
|
||||||
: /*Master thread only*/ 1;
|
: /*Master thread only*/ 1;
|
||||||
uint32_t TeamId = GetBlockIdInKernel();
|
uint32_t TeamId = GetBlockIdInKernel();
|
||||||
uint32_t NumTeams = GetNumberOfBlocksInKernel();
|
uint32_t NumTeams = GetNumberOfBlocksInKernel();
|
||||||
|
@ -225,7 +225,7 @@ EXTERN int32_t __kmpc_nvptx_teams_reduce_nowait_v2(
|
||||||
ChunkTeamCount = __kmpc_atomic_inc((uint32_t *)&Cnt, num_of_records - 1u);
|
ChunkTeamCount = __kmpc_atomic_inc((uint32_t *)&Cnt, num_of_records - 1u);
|
||||||
}
|
}
|
||||||
// Synchronize
|
// Synchronize
|
||||||
if (__kmpc_is_spmd_exec_mode())
|
if (checkSPMDMode(loc))
|
||||||
__kmpc_barrier(loc, global_tid);
|
__kmpc_barrier(loc, global_tid);
|
||||||
|
|
||||||
// reduce_data is global or shared so before being reduced within the
|
// reduce_data is global or shared so before being reduced within the
|
||||||
|
|
|
@ -34,6 +34,57 @@ bool isRuntimeInitialized() {
|
||||||
return (execution_param & RuntimeMask) == RuntimeInitialized;
|
return (execution_param & RuntimeMask) == RuntimeInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Execution Modes based on location parameter fields
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool checkSPMDMode(kmp_Ident *loc) {
|
||||||
|
if (!loc)
|
||||||
|
return __kmpc_is_spmd_exec_mode();
|
||||||
|
|
||||||
|
// If SPMD is true then we are not in the UNDEFINED state so
|
||||||
|
// we can return immediately.
|
||||||
|
if (loc->reserved_2 & KMP_IDENT_SPMD_MODE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// If not in SPMD mode and runtime required is a valid
|
||||||
|
// combination of flags so we can return immediately.
|
||||||
|
if (!(loc->reserved_2 & KMP_IDENT_SIMPLE_RT_MODE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// We are in underfined state.
|
||||||
|
return __kmpc_is_spmd_exec_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkGenericMode(kmp_Ident *loc) { return !checkSPMDMode(loc); }
|
||||||
|
|
||||||
|
bool checkRuntimeUninitialized(kmp_Ident *loc) {
|
||||||
|
if (!loc)
|
||||||
|
return isRuntimeUninitialized();
|
||||||
|
|
||||||
|
// If runtime is required then we know we can't be
|
||||||
|
// in the undefined mode. We can return immediately.
|
||||||
|
if (!(loc->reserved_2 & KMP_IDENT_SIMPLE_RT_MODE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If runtime is required then we need to check is in
|
||||||
|
// SPMD mode or not. If not in SPMD mode then we end
|
||||||
|
// up in the UNDEFINED state that marks the orphaned
|
||||||
|
// functions.
|
||||||
|
if (loc->reserved_2 & KMP_IDENT_SPMD_MODE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Check if we are in an UNDEFINED state. Undefined is denoted by
|
||||||
|
// non-SPMD + noRuntimeRequired which is a combination that
|
||||||
|
// cannot actually happen. Undefined states is used to mark orphaned
|
||||||
|
// functions.
|
||||||
|
return isRuntimeUninitialized();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkRuntimeInitialized(kmp_Ident *loc) {
|
||||||
|
return !checkRuntimeUninitialized(loc);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// support: get info from machine
|
// support: get info from machine
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -42,16 +42,16 @@ EXTERN int32_t __kmpc_cancel_barrier(kmp_Ident *loc_ref, int32_t tid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN void __kmpc_barrier(kmp_Ident *loc_ref, int32_t tid) {
|
EXTERN void __kmpc_barrier(kmp_Ident *loc_ref, int32_t tid) {
|
||||||
if (isRuntimeUninitialized()) {
|
if (checkRuntimeUninitialized(loc_ref)) {
|
||||||
ASSERT0(LT_FUSSY, __kmpc_is_spmd_exec_mode(),
|
ASSERT0(LT_FUSSY, checkSPMDMode(loc_ref),
|
||||||
"Expected SPMD mode with uninitialized runtime.");
|
"Expected SPMD mode with uninitialized runtime.");
|
||||||
__kmpc_barrier_simple_spmd(loc_ref, tid);
|
__kmpc_barrier_simple_spmd(loc_ref, tid);
|
||||||
} else {
|
} else {
|
||||||
tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc_ref));
|
||||||
int numberOfActiveOMPThreads =
|
int numberOfActiveOMPThreads =
|
||||||
GetNumberOfOmpThreads(__kmpc_is_spmd_exec_mode());
|
GetNumberOfOmpThreads(checkSPMDMode(loc_ref));
|
||||||
if (numberOfActiveOMPThreads > 1) {
|
if (numberOfActiveOMPThreads > 1) {
|
||||||
if (__kmpc_is_spmd_exec_mode()) {
|
if (checkSPMDMode(loc_ref)) {
|
||||||
__kmpc_barrier_simple_spmd(loc_ref, tid);
|
__kmpc_barrier_simple_spmd(loc_ref, tid);
|
||||||
} else {
|
} else {
|
||||||
// The #threads parameter must be rounded up to the WARPSIZE.
|
// The #threads parameter must be rounded up to the WARPSIZE.
|
||||||
|
|
|
@ -83,7 +83,7 @@ EXTERN int32_t __kmpc_omp_task_with_deps(kmp_Ident *loc, uint32_t global_tid,
|
||||||
void *noAliasDepList) {
|
void *noAliasDepList) {
|
||||||
PRINT(LD_IO, "call to __kmpc_omp_task_with_deps(task 0x%llx)\n",
|
PRINT(LD_IO, "call to __kmpc_omp_task_with_deps(task 0x%llx)\n",
|
||||||
P64(newKmpTaskDescr));
|
P64(newKmpTaskDescr));
|
||||||
ASSERT0(LT_FUSSY, isRuntimeInitialized(),
|
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||||
"Runtime must be initialized.");
|
"Runtime must be initialized.");
|
||||||
// 1. get explicit task descr from kmp task descr
|
// 1. get explicit task descr from kmp task descr
|
||||||
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
||||||
|
@ -96,7 +96,7 @@ EXTERN int32_t __kmpc_omp_task_with_deps(kmp_Ident *loc, uint32_t global_tid,
|
||||||
"bad assumptions");
|
"bad assumptions");
|
||||||
|
|
||||||
// 2. push new context: update new task descriptor
|
// 2. push new context: update new task descriptor
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_TaskDescr *parentTaskDescr = getMyTopTaskDescriptor(tid);
|
omptarget_nvptx_TaskDescr *parentTaskDescr = getMyTopTaskDescriptor(tid);
|
||||||
newTaskDescr->CopyForExplicitTask(parentTaskDescr);
|
newTaskDescr->CopyForExplicitTask(parentTaskDescr);
|
||||||
// set new task descriptor as top
|
// set new task descriptor as top
|
||||||
|
@ -122,7 +122,7 @@ EXTERN void __kmpc_omp_task_begin_if0(kmp_Ident *loc, uint32_t global_tid,
|
||||||
kmp_TaskDescr *newKmpTaskDescr) {
|
kmp_TaskDescr *newKmpTaskDescr) {
|
||||||
PRINT(LD_IO, "call to __kmpc_omp_task_begin_if0(task 0x%llx)\n",
|
PRINT(LD_IO, "call to __kmpc_omp_task_begin_if0(task 0x%llx)\n",
|
||||||
(unsigned long long)newKmpTaskDescr);
|
(unsigned long long)newKmpTaskDescr);
|
||||||
ASSERT0(LT_FUSSY, isRuntimeInitialized(),
|
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||||
"Runtime must be initialized.");
|
"Runtime must be initialized.");
|
||||||
// 1. get explicit task descr from kmp task descr
|
// 1. get explicit task descr from kmp task descr
|
||||||
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
||||||
|
@ -135,7 +135,7 @@ EXTERN void __kmpc_omp_task_begin_if0(kmp_Ident *loc, uint32_t global_tid,
|
||||||
"bad assumptions");
|
"bad assumptions");
|
||||||
|
|
||||||
// 2. push new context: update new task descriptor
|
// 2. push new context: update new task descriptor
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_TaskDescr *parentTaskDescr = getMyTopTaskDescriptor(tid);
|
omptarget_nvptx_TaskDescr *parentTaskDescr = getMyTopTaskDescriptor(tid);
|
||||||
newTaskDescr->CopyForExplicitTask(parentTaskDescr);
|
newTaskDescr->CopyForExplicitTask(parentTaskDescr);
|
||||||
// set new task descriptor as top
|
// set new task descriptor as top
|
||||||
|
@ -148,7 +148,7 @@ EXTERN void __kmpc_omp_task_complete_if0(kmp_Ident *loc, uint32_t global_tid,
|
||||||
kmp_TaskDescr *newKmpTaskDescr) {
|
kmp_TaskDescr *newKmpTaskDescr) {
|
||||||
PRINT(LD_IO, "call to __kmpc_omp_task_complete_if0(task 0x%llx)\n",
|
PRINT(LD_IO, "call to __kmpc_omp_task_complete_if0(task 0x%llx)\n",
|
||||||
(unsigned long long)newKmpTaskDescr);
|
(unsigned long long)newKmpTaskDescr);
|
||||||
ASSERT0(LT_FUSSY, isRuntimeInitialized(),
|
ASSERT0(LT_FUSSY, checkRuntimeInitialized(loc),
|
||||||
"Runtime must be initialized.");
|
"Runtime must be initialized.");
|
||||||
// 1. get explicit task descr from kmp task descr
|
// 1. get explicit task descr from kmp task descr
|
||||||
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
omptarget_nvptx_ExplicitTaskDescr *newExplicitTaskDescr =
|
||||||
|
@ -163,7 +163,7 @@ EXTERN void __kmpc_omp_task_complete_if0(kmp_Ident *loc, uint32_t global_tid,
|
||||||
omptarget_nvptx_TaskDescr *parentTaskDescr = newTaskDescr->GetPrevTaskDescr();
|
omptarget_nvptx_TaskDescr *parentTaskDescr = newTaskDescr->GetPrevTaskDescr();
|
||||||
// 3... noting to call... is inline
|
// 3... noting to call... is inline
|
||||||
// 4. pop context
|
// 4. pop context
|
||||||
int tid = GetLogicalThreadIdInBlock(__kmpc_is_spmd_exec_mode());
|
int tid = GetLogicalThreadIdInBlock(checkSPMDMode(loc));
|
||||||
omptarget_nvptx_threadPrivateContext->SetTopLevelTaskDescr(tid,
|
omptarget_nvptx_threadPrivateContext->SetTopLevelTaskDescr(tid,
|
||||||
parentTaskDescr);
|
parentTaskDescr);
|
||||||
// 5. free
|
// 5. free
|
||||||
|
|
|
@ -36,6 +36,15 @@ bool isGenericMode();
|
||||||
bool isRuntimeUninitialized();
|
bool isRuntimeUninitialized();
|
||||||
bool isRuntimeInitialized();
|
bool isRuntimeInitialized();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Execution Modes based on location parameter fields
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool checkSPMDMode(kmp_Ident *loc);
|
||||||
|
bool checkGenericMode(kmp_Ident *loc);
|
||||||
|
bool checkRuntimeUninitialized(kmp_Ident *loc);
|
||||||
|
bool checkRuntimeInitialized(kmp_Ident *loc);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// get info from machine
|
// get info from machine
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -416,11 +416,11 @@ EXTERN int32_t __kmpc_cancel(kmp_Ident *loc, int32_t global_tid,
|
||||||
int32_t cancelVal);
|
int32_t cancelVal);
|
||||||
|
|
||||||
// non standard
|
// non standard
|
||||||
EXTERN int32_t __kmpc_target_init(ident_t *Ident, bool IsSPMD,
|
EXTERN void __kmpc_kernel_init(int ThreadLimit, int16_t RequiresOMPRuntime);
|
||||||
bool UseGenericStateMachine,
|
EXTERN void __kmpc_kernel_deinit(int16_t IsOMPRuntimeInitialized);
|
||||||
bool RequiresFullRuntime);
|
EXTERN void __kmpc_spmd_kernel_init(int ThreadLimit,
|
||||||
EXTERN void __kmpc_target_deinit(ident_t *Ident, bool IsSPMD,
|
int16_t RequiresOMPRuntime);
|
||||||
bool RequiresFullRuntime);
|
EXTERN void __kmpc_spmd_kernel_deinit_v2(int16_t RequiresOMPRuntime);
|
||||||
EXTERN void __kmpc_kernel_prepare_parallel(void *WorkFn);
|
EXTERN void __kmpc_kernel_prepare_parallel(void *WorkFn);
|
||||||
EXTERN bool __kmpc_kernel_parallel(void **WorkFn);
|
EXTERN bool __kmpc_kernel_parallel(void **WorkFn);
|
||||||
EXTERN void __kmpc_kernel_end_parallel();
|
EXTERN void __kmpc_kernel_end_parallel();
|
||||||
|
|
|
@ -60,13 +60,7 @@ EXTERN __kmpc_impl_lanemask_t __kmpc_impl_activemask() {
|
||||||
return Mask;
|
return Mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERN void __kmpc_impl_syncthreads() {
|
EXTERN void __kmpc_impl_syncthreads() { __syncthreads(); }
|
||||||
int barrier = 2;
|
|
||||||
asm volatile("barrier.sync %0;"
|
|
||||||
:
|
|
||||||
: "r"(barrier)
|
|
||||||
: "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
EXTERN void __kmpc_impl_syncwarp(__kmpc_impl_lanemask_t Mask) {
|
EXTERN void __kmpc_impl_syncwarp(__kmpc_impl_lanemask_t Mask) {
|
||||||
__nvvm_bar_warp_sync(Mask);
|
__nvvm_bar_warp_sync(Mask);
|
||||||
|
@ -81,7 +75,7 @@ EXTERN void __kmpc_impl_named_sync(uint32_t num_threads) {
|
||||||
// The named barrier for active parallel threads of a team in an L1 parallel
|
// The named barrier for active parallel threads of a team in an L1 parallel
|
||||||
// region to synchronize with each other.
|
// region to synchronize with each other.
|
||||||
int barrier = 1;
|
int barrier = 1;
|
||||||
asm volatile("barrier.sync %0, %1;"
|
asm volatile("bar.sync %0, %1;"
|
||||||
:
|
:
|
||||||
: "r"(barrier), "r"(num_threads)
|
: "r"(barrier), "r"(num_threads)
|
||||||
: "memory");
|
: "memory");
|
||||||
|
|
Loading…
Reference in New Issue