forked from OSchip/llvm-project
[LoopUtils] Simplify addRuntimeCheck to return a single value.
This simplifies the return value of addRuntimeCheck from a pair of instructions to a single `Value *`. The existing users of addRuntimeChecks were ignoring the first element of the pair, hence there is not reason to track FirstInst and return it. Additionally all users of addRuntimeChecks use the second returned `Instruction *` just as `Value *`, so there is no need to return an `Instruction *`. Therefore there is no need to create a redundant dummy `and X, true` instruction any longer. Effectively this change should not impact the generated code because the redundant AND will be folded by later optimizations. But it is easy to avoid creating it in the first place and it allows more accurately estimating the cost of the runtime checks.
This commit is contained in:
parent
62bf850910
commit
e844f05397
|
@ -495,12 +495,8 @@ Loop *cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
|
||||||
LoopInfo *LI, LPPassManager *LPM);
|
LoopInfo *LI, LPPassManager *LPM);
|
||||||
|
|
||||||
/// Add code that checks at runtime if the accessed arrays in \p PointerChecks
|
/// Add code that checks at runtime if the accessed arrays in \p PointerChecks
|
||||||
/// overlap.
|
/// overlap. Returns the final comparator value or NULL if no check is needed.
|
||||||
///
|
Value *
|
||||||
/// Returns a pair of instructions where the first element is the first
|
|
||||||
/// instruction generated in possibly a sequence of instructions and the
|
|
||||||
/// second value is the final comparator value or NULL if no check is needed.
|
|
||||||
std::pair<Instruction *, Instruction *>
|
|
||||||
addRuntimeChecks(Instruction *Loc, Loop *TheLoop,
|
addRuntimeChecks(Instruction *Loc, Loop *TheLoop,
|
||||||
const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
|
const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
|
||||||
SCEVExpander &Expander);
|
SCEVExpander &Expander);
|
||||||
|
|
|
@ -1561,7 +1561,7 @@ expandBounds(const SmallVectorImpl<RuntimePointerCheck> &PointerChecks, Loop *L,
|
||||||
return ChecksWithBounds;
|
return ChecksWithBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<Instruction *, Instruction *> llvm::addRuntimeChecks(
|
Value *llvm::addRuntimeChecks(
|
||||||
Instruction *Loc, Loop *TheLoop,
|
Instruction *Loc, Loop *TheLoop,
|
||||||
const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
|
const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
|
||||||
SCEVExpander &Exp) {
|
SCEVExpander &Exp) {
|
||||||
|
@ -1570,22 +1570,10 @@ std::pair<Instruction *, Instruction *> llvm::addRuntimeChecks(
|
||||||
auto ExpandedChecks = expandBounds(PointerChecks, TheLoop, Loc, Exp);
|
auto ExpandedChecks = expandBounds(PointerChecks, TheLoop, Loc, Exp);
|
||||||
|
|
||||||
LLVMContext &Ctx = Loc->getContext();
|
LLVMContext &Ctx = Loc->getContext();
|
||||||
Instruction *FirstInst = nullptr;
|
|
||||||
IRBuilder<> ChkBuilder(Loc);
|
IRBuilder<> ChkBuilder(Loc);
|
||||||
// Our instructions might fold to a constant.
|
// Our instructions might fold to a constant.
|
||||||
Value *MemoryRuntimeCheck = nullptr;
|
Value *MemoryRuntimeCheck = nullptr;
|
||||||
|
|
||||||
// FIXME: this helper is currently a duplicate of the one in
|
|
||||||
// LoopVectorize.cpp.
|
|
||||||
auto GetFirstInst = [](Instruction *FirstInst, Value *V,
|
|
||||||
Instruction *Loc) -> Instruction * {
|
|
||||||
if (FirstInst)
|
|
||||||
return FirstInst;
|
|
||||||
if (Instruction *I = dyn_cast<Instruction>(V))
|
|
||||||
return I->getParent() == Loc->getParent() ? I : nullptr;
|
|
||||||
return nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const auto &Check : ExpandedChecks) {
|
for (const auto &Check : ExpandedChecks) {
|
||||||
const PointerBounds &A = Check.first, &B = Check.second;
|
const PointerBounds &A = Check.first, &B = Check.second;
|
||||||
// Check if two pointers (A and B) conflict where conflict is computed as:
|
// Check if two pointers (A and B) conflict where conflict is computed as:
|
||||||
|
@ -1614,30 +1602,16 @@ std::pair<Instruction *, Instruction *> llvm::addRuntimeChecks(
|
||||||
// bound1 = (A.Start < B.End)
|
// bound1 = (A.Start < B.End)
|
||||||
// IsConflict = bound0 & bound1
|
// IsConflict = bound0 & bound1
|
||||||
Value *Cmp0 = ChkBuilder.CreateICmpULT(Start0, End1, "bound0");
|
Value *Cmp0 = ChkBuilder.CreateICmpULT(Start0, End1, "bound0");
|
||||||
FirstInst = GetFirstInst(FirstInst, Cmp0, Loc);
|
|
||||||
Value *Cmp1 = ChkBuilder.CreateICmpULT(Start1, End0, "bound1");
|
Value *Cmp1 = ChkBuilder.CreateICmpULT(Start1, End0, "bound1");
|
||||||
FirstInst = GetFirstInst(FirstInst, Cmp1, Loc);
|
|
||||||
Value *IsConflict = ChkBuilder.CreateAnd(Cmp0, Cmp1, "found.conflict");
|
Value *IsConflict = ChkBuilder.CreateAnd(Cmp0, Cmp1, "found.conflict");
|
||||||
FirstInst = GetFirstInst(FirstInst, IsConflict, Loc);
|
|
||||||
if (MemoryRuntimeCheck) {
|
if (MemoryRuntimeCheck) {
|
||||||
IsConflict =
|
IsConflict =
|
||||||
ChkBuilder.CreateOr(MemoryRuntimeCheck, IsConflict, "conflict.rdx");
|
ChkBuilder.CreateOr(MemoryRuntimeCheck, IsConflict, "conflict.rdx");
|
||||||
FirstInst = GetFirstInst(FirstInst, IsConflict, Loc);
|
|
||||||
}
|
}
|
||||||
MemoryRuntimeCheck = IsConflict;
|
MemoryRuntimeCheck = IsConflict;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MemoryRuntimeCheck)
|
return MemoryRuntimeCheck;
|
||||||
return std::make_pair(nullptr, nullptr);
|
|
||||||
|
|
||||||
// We have to do this trickery because the IRBuilder might fold the check to a
|
|
||||||
// constant expression in which case there is no Instruction anchored in a
|
|
||||||
// the block.
|
|
||||||
Instruction *Check =
|
|
||||||
BinaryOperator::CreateAnd(MemoryRuntimeCheck, ConstantInt::getTrue(Ctx));
|
|
||||||
ChkBuilder.Insert(Check, "memcheck.conflict");
|
|
||||||
FirstInst = GetFirstInst(FirstInst, Check, Loc);
|
|
||||||
return std::make_pair(FirstInst, Check);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<IVConditionInfo> llvm::hasPartialIVCondition(Loop &L,
|
Optional<IVConditionInfo> llvm::hasPartialIVCondition(Loop &L,
|
||||||
|
|
|
@ -52,8 +52,7 @@ void LoopVersioning::versionLoop(
|
||||||
assert(VersionedLoop->isLoopSimplifyForm() &&
|
assert(VersionedLoop->isLoopSimplifyForm() &&
|
||||||
"Loop is not in loop-simplify form");
|
"Loop is not in loop-simplify form");
|
||||||
|
|
||||||
Instruction *FirstCheckInst;
|
Value *MemRuntimeCheck;
|
||||||
Instruction *MemRuntimeCheck;
|
|
||||||
Value *SCEVRuntimeCheck;
|
Value *SCEVRuntimeCheck;
|
||||||
Value *RuntimeCheck = nullptr;
|
Value *RuntimeCheck = nullptr;
|
||||||
|
|
||||||
|
@ -64,8 +63,8 @@ void LoopVersioning::versionLoop(
|
||||||
SCEVExpander Exp2(*RtPtrChecking.getSE(),
|
SCEVExpander Exp2(*RtPtrChecking.getSE(),
|
||||||
VersionedLoop->getHeader()->getModule()->getDataLayout(),
|
VersionedLoop->getHeader()->getModule()->getDataLayout(),
|
||||||
"induction");
|
"induction");
|
||||||
std::tie(FirstCheckInst, MemRuntimeCheck) = addRuntimeChecks(
|
MemRuntimeCheck = addRuntimeChecks(RuntimeCheckBB->getTerminator(),
|
||||||
RuntimeCheckBB->getTerminator(), VersionedLoop, AliasChecks, Exp2);
|
VersionedLoop, AliasChecks, Exp2);
|
||||||
|
|
||||||
SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
|
SCEVExpander Exp(*SE, RuntimeCheckBB->getModule()->getDataLayout(),
|
||||||
"scev.check");
|
"scev.check");
|
||||||
|
|
|
@ -1925,7 +1925,7 @@ class GeneratedRTChecks {
|
||||||
/// The value representing the result of the generated memory runtime checks.
|
/// The value representing the result of the generated memory runtime checks.
|
||||||
/// If it is nullptr, either no memory runtime checks have been generated or
|
/// If it is nullptr, either no memory runtime checks have been generated or
|
||||||
/// they have been used.
|
/// they have been used.
|
||||||
Instruction *MemRuntimeCheckCond = nullptr;
|
Value *MemRuntimeCheckCond = nullptr;
|
||||||
|
|
||||||
DominatorTree *DT;
|
DominatorTree *DT;
|
||||||
LoopInfo *LI;
|
LoopInfo *LI;
|
||||||
|
@ -1968,7 +1968,7 @@ public:
|
||||||
MemCheckBlock = SplitBlock(Pred, Pred->getTerminator(), DT, LI, nullptr,
|
MemCheckBlock = SplitBlock(Pred, Pred->getTerminator(), DT, LI, nullptr,
|
||||||
"vector.memcheck");
|
"vector.memcheck");
|
||||||
|
|
||||||
std::tie(std::ignore, MemRuntimeCheckCond) =
|
MemRuntimeCheckCond =
|
||||||
addRuntimeChecks(MemCheckBlock->getTerminator(), L,
|
addRuntimeChecks(MemCheckBlock->getTerminator(), L,
|
||||||
RtPtrChecking.getChecks(), MemCheckExp);
|
RtPtrChecking.getChecks(), MemCheckExp);
|
||||||
assert(MemRuntimeCheckCond &&
|
assert(MemRuntimeCheckCond &&
|
||||||
|
|
|
@ -54,7 +54,7 @@ entry:
|
||||||
; CHECK: = icmp
|
; CHECK: = icmp
|
||||||
|
|
||||||
; CHECK-NOT: = icmp
|
; CHECK-NOT: = icmp
|
||||||
; CHECK: br i1 %memcheck.conflict, label %for.body.ph.lver.orig, label %for.body.ph.ldist1
|
; CHECK: br i1 %conflict.rdx25, label %for.body.ph.lver.orig, label %for.body.ph.ldist1
|
||||||
|
|
||||||
; The non-distributed loop that the memchecks fall back on.
|
; The non-distributed loop that the memchecks fall back on.
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,7 @@ define void @foo1(i32* nocapture %A, i32* nocapture readonly %B, i32* nocapture
|
||||||
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX1-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX1-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX1-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX1: vector.ph:
|
; AVX1: vector.ph:
|
||||||
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX1: vector.body:
|
; AVX1: vector.body:
|
||||||
|
@ -108,8 +107,7 @@ define void @foo1(i32* nocapture %A, i32* nocapture readonly %B, i32* nocapture
|
||||||
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX2-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX2-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX2-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX2: vector.ph:
|
; AVX2: vector.ph:
|
||||||
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX2: vector.body:
|
; AVX2: vector.body:
|
||||||
|
@ -223,8 +221,7 @@ define void @foo1(i32* nocapture %A, i32* nocapture readonly %B, i32* nocapture
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
|
||||||
; AVX512: vector.main.loop.iter.check:
|
; AVX512: vector.main.loop.iter.check:
|
||||||
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
|
@ -400,8 +397,7 @@ define void @foo1_addrspace1(i32 addrspace(1)* nocapture %A, i32 addrspace(1)* n
|
||||||
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX1-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX1-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX1-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX1: vector.ph:
|
; AVX1: vector.ph:
|
||||||
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX1: vector.body:
|
; AVX1: vector.body:
|
||||||
|
@ -470,8 +466,7 @@ define void @foo1_addrspace1(i32 addrspace(1)* nocapture %A, i32 addrspace(1)* n
|
||||||
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX2-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX2-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX2-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX2: vector.ph:
|
; AVX2: vector.ph:
|
||||||
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX2: vector.body:
|
; AVX2: vector.body:
|
||||||
|
@ -585,8 +580,7 @@ define void @foo1_addrspace1(i32 addrspace(1)* nocapture %A, i32 addrspace(1)* n
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8 addrspace(1)* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
|
||||||
; AVX512: vector.main.loop.iter.check:
|
; AVX512: vector.main.loop.iter.check:
|
||||||
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
|
@ -771,8 +765,7 @@ define void @foo2(float* nocapture %A, float* nocapture readonly %B, i32* nocapt
|
||||||
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX1-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX1-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX1-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX1-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX1-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX1-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX1: vector.ph:
|
; AVX1: vector.ph:
|
||||||
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX1-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX1: vector.body:
|
; AVX1: vector.body:
|
||||||
|
@ -843,8 +836,7 @@ define void @foo2(float* nocapture %A, float* nocapture readonly %B, i32* nocapt
|
||||||
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX2-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX2-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX2-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX2: vector.ph:
|
; AVX2: vector.ph:
|
||||||
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX2: vector.body:
|
; AVX2: vector.body:
|
||||||
|
@ -963,8 +955,7 @@ define void @foo2(float* nocapture %A, float* nocapture readonly %B, i32* nocapt
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[VEC_EPILOG_SCALAR_PH]], label [[VECTOR_MAIN_LOOP_ITER_CHECK:%.*]]
|
|
||||||
; AVX512: vector.main.loop.iter.check:
|
; AVX512: vector.main.loop.iter.check:
|
||||||
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
; AVX512-NEXT: br i1 false, label [[VEC_EPILOG_PH:%.*]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
|
@ -1156,8 +1147,7 @@ define void @foo3(double* nocapture %A, double* nocapture readonly %B, i32* noca
|
||||||
; AVX-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX: vector.ph:
|
; AVX: vector.ph:
|
||||||
; AVX-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX: vector.body:
|
; AVX: vector.body:
|
||||||
|
@ -1276,8 +1266,7 @@ define void @foo3(double* nocapture %A, double* nocapture readonly %B, i32* noca
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX512: vector.body:
|
; AVX512: vector.body:
|
||||||
|
@ -1461,8 +1450,7 @@ define void @foo4(double* nocapture %A, double* nocapture readonly %B, i32* noca
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[B6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX512: vector.body:
|
; AVX512: vector.body:
|
||||||
|
@ -1664,8 +1652,7 @@ define void @foo6(double* nocapture readonly %in, double* nocapture %out, i32 %s
|
||||||
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[IN6]], [[SCEVGEP2]]
|
; AVX2-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[IN6]], [[SCEVGEP2]]
|
||||||
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX2-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX2-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX2-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX2-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX2-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX2: vector.ph:
|
; AVX2: vector.ph:
|
||||||
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX2-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX2: vector.body:
|
; AVX2: vector.body:
|
||||||
|
@ -1808,8 +1795,7 @@ define void @foo6(double* nocapture readonly %in, double* nocapture %out, i32 %s
|
||||||
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[IN6]], [[SCEVGEP2]]
|
; AVX512-NEXT: [[BOUND110:%.*]] = icmp ult i8* [[IN6]], [[SCEVGEP2]]
|
||||||
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
; AVX512-NEXT: [[FOUND_CONFLICT11:%.*]] = and i1 [[BOUND09]], [[BOUND110]]
|
||||||
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
; AVX512-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT11]]
|
||||||
; AVX512-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; AVX512-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; AVX512-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; AVX512: vector.ph:
|
; AVX512: vector.ph:
|
||||||
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
; AVX512-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; AVX512: vector.body:
|
; AVX512: vector.body:
|
||||||
|
|
|
@ -399,8 +399,7 @@ define void @uniform_copy(i32* %A, i32* %B) {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; CHECK: vector.body:
|
; CHECK: vector.body:
|
||||||
|
|
|
@ -55,8 +55,7 @@ define void @Test(%struct.s* nocapture %obj, i64 %z) #0 {
|
||||||
; CHECK-NEXT: [[BOUND112:%.*]] = icmp ult i8* [[SCEVGEP78]], [[SCEVGEP23]]
|
; CHECK-NEXT: [[BOUND112:%.*]] = icmp ult i8* [[SCEVGEP78]], [[SCEVGEP23]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT13:%.*]] = and i1 [[BOUND011]], [[BOUND112]]
|
; CHECK-NEXT: [[FOUND_CONFLICT13:%.*]] = and i1 [[BOUND011]], [[BOUND112]]
|
||||||
; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT13]]
|
; CHECK-NEXT: [[CONFLICT_RDX:%.*]] = or i1 [[FOUND_CONFLICT]], [[FOUND_CONFLICT13]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[CONFLICT_RDX]], true
|
; CHECK-NEXT: br i1 [[CONFLICT_RDX]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[Z]], 4
|
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[Z]], 4
|
||||||
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[Z]], [[N_MOD_VF]]
|
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[Z]], [[N_MOD_VF]]
|
||||||
|
|
|
@ -334,7 +334,7 @@ for.end: ; preds = %for.body, %entry
|
||||||
; loop
|
; loop
|
||||||
; CHECK-LABEL: sum_arrays_outside_use(
|
; CHECK-LABEL: sum_arrays_outside_use(
|
||||||
; CHECK-LABEL: vector.memcheck:
|
; CHECK-LABEL: vector.memcheck:
|
||||||
; CHECK: br i1 %memcheck.conflict, label %scalar.ph, label %vector.ph
|
; CHECK: br i1 %conflict.rdx, label %scalar.ph, label %vector.ph
|
||||||
|
|
||||||
; CHECK-LABEL: vector.body:
|
; CHECK-LABEL: vector.body:
|
||||||
; CHECK: %wide.load = load <2 x i32>, <2 x i32>*
|
; CHECK: %wide.load = load <2 x i32>, <2 x i32>*
|
||||||
|
|
|
@ -41,8 +41,7 @@ define void @f() {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* bitcast (i32* @f.e to i8*), [[SCEVGEP]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* bitcast (i32* @f.e to i8*), [[SCEVGEP]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[TMP1]], bitcast (i32* getelementptr inbounds (i32, i32* @f.e, i64 1) to i8*)
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[TMP1]], bitcast (i32* getelementptr inbounds (i32, i32* @f.e, i64 1) to i8*)
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; CHECK: vector.body:
|
; CHECK: vector.body:
|
||||||
|
|
|
@ -17,8 +17,7 @@ define void @m(i32* nocapture %p, i32* nocapture %p2, i32 %q) {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[P1]], [[SCEVGEP45]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[P1]], [[SCEVGEP45]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[P23]], [[SCEVGEP2]]
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[P23]], [[SCEVGEP2]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
|
||||||
; CHECK: vector.body:
|
; CHECK: vector.body:
|
||||||
|
|
|
@ -44,8 +44,7 @@ define void @load_clamped_index(i32* %A, i32* %B, i32 %N) {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N]], 2
|
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N]], 2
|
||||||
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N]], [[N_MOD_VF]]
|
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N]], [[N_MOD_VF]]
|
||||||
|
@ -140,8 +139,7 @@ define void @store_clamped_index(i32* %A, i32* %B, i32 %N) {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[B1]], [[SCEVGEP45]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[A3]], [[SCEVGEP2]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N]], 2
|
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[N]], 2
|
||||||
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N]], [[N_MOD_VF]]
|
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[N]], [[N_MOD_VF]]
|
||||||
|
|
|
@ -41,8 +41,7 @@ define i16 @test(i16** %arg, i64 %N) {
|
||||||
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[L_2_LCSSA3]], [[SCEVGEP912]]
|
; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult i8* [[L_2_LCSSA3]], [[SCEVGEP912]]
|
||||||
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[SCEVGEP58]], [[SCEVGEP4]]
|
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[SCEVGEP58]], [[SCEVGEP4]]
|
||||||
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
|
||||||
; CHECK-NEXT: [[MEMCHECK_CONFLICT:%.*]] = and i1 [[FOUND_CONFLICT]], true
|
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
||||||
; CHECK-NEXT: br i1 [[MEMCHECK_CONFLICT]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]]
|
|
||||||
; CHECK: vector.ph:
|
; CHECK: vector.ph:
|
||||||
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 2
|
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP0]], 2
|
||||||
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
|
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP0]], [[N_MOD_VF]]
|
||||||
|
|
|
@ -15,7 +15,7 @@ entry:
|
||||||
; CHECK: icmp
|
; CHECK: icmp
|
||||||
; CHECK: icmp
|
; CHECK: icmp
|
||||||
; CHECK-NOT: icmp
|
; CHECK-NOT: icmp
|
||||||
; CHECK: br i1 %memcheck.conflict, label %for.body.ph.lver.orig, label %for.body.ph
|
; CHECK: br i1 %conflict.rdx, label %for.body.ph.lver.orig, label %for.body.ph
|
||||||
|
|
||||||
; CHECK: for.body.ph.lver.orig:
|
; CHECK: for.body.ph.lver.orig:
|
||||||
; CHECK: for.body.lver.orig:
|
; CHECK: for.body.lver.orig:
|
||||||
|
|
|
@ -3,7 +3,7 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
define void @fill(i8** %ls1.20, i8** %ls2.21, i8* %cse3.22) {
|
define void @fill(i8** %ls1.20, i8** %ls2.21, i8* %cse3.22) {
|
||||||
; CHECK: bb1.lver.check:
|
; CHECK: bb1.lver.check:
|
||||||
; CHECK: br i1 %memcheck.conflict, label %bb1.ph.lver.orig, label %bb1.ph
|
; CHECK: br i1 %found.conflict, label %bb1.ph.lver.orig, label %bb1.ph
|
||||||
bb1.ph:
|
bb1.ph:
|
||||||
%ls1.20.promoted = load i8*, i8** %ls1.20
|
%ls1.20.promoted = load i8*, i8** %ls1.20
|
||||||
%ls2.21.promoted = load i8*, i8** %ls2.21
|
%ls2.21.promoted = load i8*, i8** %ls2.21
|
||||||
|
@ -37,7 +37,7 @@ bb3:
|
||||||
define void @fill_no_null_opt(i8** %ls1.20, i8** %ls2.21, i8* %cse3.22) #0 {
|
define void @fill_no_null_opt(i8** %ls1.20, i8** %ls2.21, i8* %cse3.22) #0 {
|
||||||
; CHECK-LABEL: fill_no_null_opt(
|
; CHECK-LABEL: fill_no_null_opt(
|
||||||
; CHECK: bb1.lver.check:
|
; CHECK: bb1.lver.check:
|
||||||
; CHECK: %lver.safe = or i1 %memcheck.conflict, %{{.*}}
|
; CHECK: %lver.safe = or i1 %found.conflict, %{{.*}}
|
||||||
; CHECK: br i1 %lver.safe, label %bb1.ph.lver.orig, label %bb1.ph
|
; CHECK: br i1 %lver.safe, label %bb1.ph.lver.orig, label %bb1.ph
|
||||||
bb1.ph:
|
bb1.ph:
|
||||||
%ls1.20.promoted = load i8*, i8** %ls1.20
|
%ls1.20.promoted = load i8*, i8** %ls1.20
|
||||||
|
|
Loading…
Reference in New Issue