1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ScalarEvolution] Make getMinusSCEV() fail for unrelated pointers.

As part of making ScalarEvolution's handling of pointers consistent, we
want to forbid multiplying a pointer by -1 (or any other value). This
means we can't blindly subtract pointers.

There are a few ways we could deal with this:
1. We could completely forbid subtracting pointers in getMinusSCEV()
2. We could forbid subracting pointers with different pointer bases
(this patch).
3. We could try to ptrtoint pointer operands.

The option in this patch is more friendly to non-integral pointers: code
that works with normal pointers will also work with non-integral
pointers. And it seems like there are very few places that actually
benefit from the third option.

As a minimal patch, the ScalarEvolution implementation of getMinusSCEV
still ends up subtracting pointers if they have the same base.  This
should eliminate the shared pointer base, but eventually we'll need to
rewrite it to avoid negating the pointer base. I plan to do this as a
separate step to allow measuring the compile-time impact.

This doesn't cause obvious functional changes in most cases; the one
case that is significantly affected is ICmpZero handling in LSR (which
is the source of almost all the test changes).  The resulting changes
seem okay to me, but suggestions welcome.  As an alternative, I tried
explicitly ptrtoint'ing the operands, but the result doesn't seem
obviously better.

I deleted the test lsr-undef-in-binop.ll becuase I couldn't figure out
how to repair it to test what it was actually trying to test.

Differential Revision: https://reviews.llvm.org/D104806
This commit is contained in:
Eli Friedman 2021-07-06 10:54:41 -07:00
parent e4905eeb01
commit b011bc0424
20 changed files with 121 additions and 362 deletions

View File

@ -633,6 +633,12 @@ public:
const SCEV *getNotSCEV(const SCEV *V);
/// Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
///
/// If the LHS and RHS are pointers which don't share a common base
/// (according to getPointerBase()), this returns a SCEVCouldNotCompute.
/// To compute the difference between two unrelated pointers, you can
/// explicitly convert the arguments using getPtrToIntExpr(), for pointer
/// types that support it.
const SCEV *getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
SCEV::NoWrapFlags Flags = SCEV::FlagAnyWrap,
unsigned Depth = 0);

View File

@ -4138,6 +4138,15 @@ const SCEV *ScalarEvolution::getMinusSCEV(const SCEV *LHS, const SCEV *RHS,
if (LHS == RHS)
return getZero(LHS->getType());
// If we subtract two pointers with different pointer bases, bail.
// Eventually, we're going to add an assertion to getMulExpr that we
// can't multiply by a pointer.
if (RHS->getType()->isPointerTy()) {
if (!LHS->getType()->isPointerTy() ||
getPointerBase(LHS) != getPointerBase(RHS))
return getCouldNotCompute();
}
// We represent LHS - RHS as LHS + (-1)*RHS. This transformation
// makes it so that we cannot make much use of NUW.
auto AddFlags = SCEV::FlagAnyWrap;
@ -8029,6 +8038,16 @@ ScalarEvolution::computeExitLimitFromICmp(const Loop *L,
}
case ICmpInst::ICMP_EQ: { // while (X == Y)
// Convert to: while (X-Y == 0)
if (LHS->getType()->isPointerTy()) {
LHS = getLosslessPtrToIntExpr(LHS);
if (isa<SCEVCouldNotCompute>(LHS))
return LHS;
}
if (RHS->getType()->isPointerTy()) {
RHS = getLosslessPtrToIntExpr(RHS);
if (isa<SCEVCouldNotCompute>(RHS))
return RHS;
}
ExitLimit EL = howFarToNonZero(getMinusSCEV(LHS, RHS), L);
if (EL.hasAnyInfo()) return EL;
break;
@ -10066,10 +10085,13 @@ bool ScalarEvolution::isKnownPredicateViaConstantRanges(
if (Pred == CmpInst::ICMP_EQ)
return false;
if (Pred == CmpInst::ICMP_NE)
return CheckRanges(getSignedRange(LHS), getSignedRange(RHS)) ||
CheckRanges(getUnsignedRange(LHS), getUnsignedRange(RHS)) ||
isKnownNonZero(getMinusSCEV(LHS, RHS));
if (Pred == CmpInst::ICMP_NE) {
if (CheckRanges(getSignedRange(LHS), getSignedRange(RHS)) ||
CheckRanges(getUnsignedRange(LHS), getUnsignedRange(RHS)))
return true;
auto *Diff = getMinusSCEV(LHS, RHS);
return !isa<SCEVCouldNotCompute>(Diff) && isKnownNonZero(Diff);
}
if (CmpInst::isSigned(Pred))
return CheckRanges(getSignedRange(LHS), getSignedRange(RHS));
@ -10590,6 +10612,10 @@ bool ScalarEvolution::isImpliedCondBalancedTypes(
if (!isa<SCEVConstant>(FoundRHS) && !isa<SCEVAddRecExpr>(FoundLHS))
return isImpliedCondOperands(Pred, LHS, RHS, FoundRHS, FoundLHS, Context);
// Don't try to getNotSCEV pointers.
if (LHS->getType()->isPointerTy() || FoundLHS->getType()->isPointerTy())
return false;
// There's no clear preference between forms 3. and 4., try both.
return isImpliedCondOperands(FoundPred, getNotSCEV(LHS), getNotSCEV(RHS),
FoundLHS, FoundRHS, Context) ||

View File

@ -57,7 +57,8 @@ AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
// Test whether the difference is known to be great enough that memory of
// the given sizes don't overlap. This assumes that ASizeInt and BSizeInt
// are non-zero, which is special-cased above.
if (ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) &&
if (!isa<SCEVCouldNotCompute>(BA) &&
ASizeInt.ule(SE.getUnsignedRange(BA).getUnsignedMin()) &&
(-BSizeInt).uge(SE.getUnsignedRange(BA).getUnsignedMax()))
return AliasResult::NoAlias;
@ -71,7 +72,8 @@ AliasResult SCEVAAResult::alias(const MemoryLocation &LocA,
// Test whether the difference is known to be great enough that memory of
// the given sizes don't overlap. This assumes that ASizeInt and BSizeInt
// are non-zero, which is special-cased above.
if (BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) &&
if (!isa<SCEVCouldNotCompute>(AB) &&
BSizeInt.ule(SE.getUnsignedRange(AB).getUnsignedMin()) &&
(-ASizeInt).uge(SE.getUnsignedRange(AB).getUnsignedMax()))
return AliasResult::NoAlias;
}

View File

@ -263,6 +263,8 @@ ConstantRange StackSafetyLocalAnalysis::offsetFrom(Value *Addr, Value *Base) {
const SCEV *AddrExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Addr), PtrTy);
const SCEV *BaseExp = SE.getTruncateOrZeroExtend(SE.getSCEV(Base), PtrTy);
const SCEV *Diff = SE.getMinusSCEV(AddrExp, BaseExp);
if (isa<SCEVCouldNotCompute>(Diff))
return UnknownRange;
ConstantRange Offset = SE.getSignedRange(Diff);
if (isUnsafe(Offset))

View File

@ -135,6 +135,8 @@ static Align getNewAlignment(const SCEV *AASCEV, const SCEV *AlignSCEV,
PtrSCEV = SE->getTruncateOrZeroExtend(
PtrSCEV, SE->getEffectiveSCEVType(AASCEV->getType()));
const SCEV *DiffSCEV = SE->getMinusSCEV(PtrSCEV, AASCEV);
if (isa<SCEVCouldNotCompute>(DiffSCEV))
return Align(1);
// On 32-bit platforms, DiffSCEV might now have type i32 -- we've always
// sign-extended OffSCEV to i64, so make sure they agree again.

View File

@ -911,6 +911,8 @@ bool LoopReroll::DAGRootTracker::validateRootSet(DAGRootSet &DRS) {
// Check that the first root is evenly spaced.
unsigned N = DRS.Roots.size() + 1;
const SCEV *StepSCEV = SE->getMinusSCEV(SE->getSCEV(DRS.Roots[0]), ADR);
if (isa<SCEVCouldNotCompute>(StepSCEV))
return false;
const SCEV *ScaleSCEV = SE->getConstant(StepSCEV->getType(), N);
if (ADR->getStepRecurrence(*SE) != SE->getMulExpr(StepSCEV, ScaleSCEV))
return false;

View File

@ -2963,7 +2963,7 @@ void LSRInstance::ChainInstruction(Instruction *UserInst, Instruction *IVOper,
// The increment must be loop-invariant so it can be kept in a register.
const SCEV *PrevExpr = SE.getSCEV(PrevIV);
const SCEV *IncExpr = SE.getMinusSCEV(OperExpr, PrevExpr);
if (!SE.isLoopInvariant(IncExpr, L))
if (isa<SCEVCouldNotCompute>(IncExpr) || !SE.isLoopInvariant(IncExpr, L))
continue;
if (Chain.isProfitableIncrement(OperExpr, IncExpr, SE)) {
@ -3316,7 +3316,9 @@ void LSRInstance::CollectFixupsAndInitialFormulae() {
// x == y --> x - y == 0
const SCEV *N = SE.getSCEV(NV);
if (SE.isLoopInvariant(N, L) && isSafeToExpand(N, SE)) {
if (SE.isLoopInvariant(N, L) && isSafeToExpand(N, SE) &&
(!NV->getType()->isPointerTy() ||
SE.getPointerBase(N) == SE.getPointerBase(S))) {
// S is normalized, so normalize N before folding it into S
// to keep the result normalized.
N = normalizeForPostIncUse(N, TmpPostIncLoops, SE);

View File

@ -71,7 +71,7 @@ define void @StoreInBounds4() {
; CHECK-LABEL: @StoreInBounds4 dso_preemptable{{$}}
; CHECK-NEXT: args uses:
; CHECK-NEXT: allocas uses:
; CHECK-NEXT: x[4]: [-9223372036854775808,9223372036854775807){{$}}
; CHECK-NEXT: x[4]: full-set{{$}}
; CHECK-EMPTY:
entry:
%x = alloca i32, align 4

View File

@ -1,251 +0,0 @@
; REQUIRES: arm-registered-target
; RUN: opt -S -loop-reduce %s -o - | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "armv8-unknown-hurd-eabihf"
%"class.std::__1::vector.182" = type { %"class.std::__1::__vector_base.183" }
%"class.std::__1::__vector_base.183" = type { i8*, i8*, %"class.std::__1::__compressed_pair.184" }
%"class.std::__1::__compressed_pair.184" = type { %"struct.std::__1::__compressed_pair_elem.185" }
%"struct.std::__1::__compressed_pair_elem.185" = type { i8* }
%"class.std::__1::__vector_base_common" = type { i8 }
$vector_insert = comdat any
declare i8* @Allocate(i32) local_unnamed_addr
declare void @Free(i8*) local_unnamed_addr
declare void @_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(%"class.std::__1::__vector_base_common"*) local_unnamed_addr
declare i8* @memmove(i8*, i8*, i32) local_unnamed_addr
; Function Attrs: noimplicitfloat nounwind uwtable
define linkonce_odr i32 @vector_insert(%"class.std::__1::vector.182"*, [1 x i32], i8*, i8*) local_unnamed_addr #1 comdat align 2 {
; CHECK-LABEL: vector_insert
%5 = extractvalue [1 x i32] %1, 0
%6 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 0
%7 = load i8*, i8** %6, align 4
; CHECK: [[LOAD:%[0-9]+]] = load i8*, i8**
%8 = bitcast %"class.std::__1::vector.182"* %0 to i32*
%9 = ptrtoint i8* %7 to i32
; CHECK: [[NEW_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32
; CHECK: [[OLD_CAST:%[0-9]+]] = ptrtoint i8* [[LOAD]] to i32
%10 = sub i32 %5, %9
%11 = getelementptr inbounds i8, i8* %7, i32 %10
%12 = ptrtoint i8* %3 to i32
%13 = ptrtoint i8* %2 to i32
%14 = sub i32 %12, %13
%15 = icmp sgt i32 %14, 0
br i1 %15, label %18, label %16
; <label>:16: ; preds = %4
%17 = ptrtoint i8* %11 to i32
br label %148
; <label>:18: ; preds = %4
%19 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 2, i32 0, i32 0
%20 = bitcast i8** %19 to i32*
%21 = load i32, i32* %20, align 4
%22 = getelementptr inbounds %"class.std::__1::vector.182", %"class.std::__1::vector.182"* %0, i32 0, i32 0, i32 1
%23 = load i8*, i8** %22, align 4
%24 = ptrtoint i8* %23 to i32
%25 = sub i32 %21, %24
%26 = icmp sgt i32 %14, %25
%27 = bitcast i8** %22 to i32*
br i1 %26, label %77, label %28
; <label>:28: ; preds = %18
%29 = ptrtoint i8* %11 to i32
%30 = sub i32 %24, %29
%31 = icmp sgt i32 %14, %30
br i1 %31, label %32, label %48
; <label>:32: ; preds = %28
%33 = getelementptr inbounds i8, i8* %2, i32 %30
%34 = icmp eq i8* %33, %3
br i1 %34, label %43, label %35
; <label>:35: ; preds = %32, %35
%36 = phi i8* [ %41, %35 ], [ %23, %32 ]
%37 = phi i8* [ %39, %35 ], [ %33, %32 ]
%38 = load i8, i8* %37, align 1
store i8 %38, i8* %36, align 1
%39 = getelementptr inbounds i8, i8* %37, i32 1
%40 = load i8*, i8** %22, align 4
%41 = getelementptr inbounds i8, i8* %40, i32 1
store i8* %41, i8** %22, align 4
%42 = icmp eq i8* %39, %3
br i1 %42, label %43, label %35
; <label>:43: ; preds = %35, %32
%44 = phi i8* [ %23, %32 ], [ %41, %35 ]
%45 = icmp sgt i32 %30, 0
br i1 %45, label %46, label %148
; <label>:46: ; preds = %43
%47 = ptrtoint i8* %44 to i32
br label %48
; <label>:48: ; preds = %46, %28
%49 = phi i32 [ %47, %46 ], [ %24, %28 ]
%50 = phi i8* [ %44, %46 ], [ %23, %28 ]
%51 = phi i8* [ %33, %46 ], [ %3, %28 ]
%52 = getelementptr inbounds i8, i8* %11, i32 %14
%53 = ptrtoint i8* %52 to i32
%54 = sub i32 %49, %53
%55 = getelementptr inbounds i8, i8* %11, i32 %54
%56 = icmp ult i8* %55, %23
br i1 %56, label %63, label %57
; <label>:57: ; preds = %63, %48
%58 = icmp eq i32 %54, 0
br i1 %58, label %71, label %59
; <label>:59: ; preds = %57
%60 = sub i32 0, %54
%61 = getelementptr inbounds i8, i8* %50, i32 %60
%62 = tail call i8* @memmove(i8* %61, i8* %11, i32 %54) #13
br label %71
; <label>:63: ; preds = %48, %63
%64 = phi i8* [ %69, %63 ], [ %50, %48 ]
%65 = phi i8* [ %67, %63 ], [ %55, %48 ]
%66 = load i8, i8* %65, align 1
store i8 %66, i8* %64, align 1
%67 = getelementptr inbounds i8, i8* %65, i32 1
%68 = load i8*, i8** %22, align 4
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %22, align 4
%70 = icmp eq i8* %67, %23
br i1 %70, label %57, label %63
; <label>:71: ; preds = %57, %59
%72 = ptrtoint i8* %51 to i32
%73 = sub i32 %72, %13
%74 = icmp eq i32 %73, 0
br i1 %74, label %148, label %75
; <label>:75: ; preds = %71
%76 = tail call i8* @memmove(i8* %11, i8* %2, i32 %73) #13
br label %148
; <label>:77: ; preds = %18
%78 = sub i32 %24, %9
%79 = add i32 %78, %14
%80 = icmp slt i32 %79, 0
br i1 %80, label %81, label %83
; <label>:81: ; preds = %77
%82 = bitcast %"class.std::__1::vector.182"* %0 to %"class.std::__1::__vector_base_common"*
tail call void @_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv(%"class.std::__1::__vector_base_common"* %82) #15
unreachable
; <label>:83: ; preds = %77
%84 = sub i32 %21, %9
%85 = icmp ult i32 %84, 1073741823
br i1 %85, label %86, label %91
; <label>:86: ; preds = %83
%87 = shl i32 %84, 1
%88 = icmp ult i32 %87, %79
%89 = select i1 %88, i32 %79, i32 %87
%90 = icmp eq i32 %89, 0
br i1 %90, label %94, label %91
; <label>:91: ; preds = %83, %86
%92 = phi i32 [ %89, %86 ], [ 2147483647, %83 ]
%93 = tail call i8* @Allocate(i32 %92) #13
br label %94
; <label>:94: ; preds = %86, %91
%95 = phi i32 [ %92, %91 ], [ 0, %86 ]
%96 = phi i8* [ %93, %91 ], [ null, %86 ]
%97 = getelementptr inbounds i8, i8* %96, i32 %10
%98 = ptrtoint i8* %97 to i32
%99 = getelementptr inbounds i8, i8* %96, i32 %95
%100 = ptrtoint i8* %99 to i32
%101 = icmp eq i8* %2, %3
br i1 %101, label %111, label %102
; <label>:102: ; preds = %94, %102
%103 = phi i8* [ %106, %102 ], [ %97, %94 ]
%104 = phi i8* [ %107, %102 ], [ %2, %94 ]
%105 = load i8, i8* %104, align 1
store i8 %105, i8* %103, align 1
%106 = getelementptr inbounds i8, i8* %103, i32 1
%107 = getelementptr inbounds i8, i8* %104, i32 1
%108 = icmp eq i8* %107, %3
br i1 %108, label %109, label %102
; <label>:109: ; preds = %102
%110 = ptrtoint i8* %106 to i32
br label %111
; <label>:111: ; preds = %109, %94
%112 = phi i32 [ %98, %94 ], [ %110, %109 ]
%113 = load i8*, i8** %6, align 4
%114 = icmp eq i8* %113, %11
br i1 %114, label %124, label %115
; CHECK-LABEL: .preheader:
; CHECK-NEXT: sub i32 [[OLD_CAST]], [[NEW_CAST]]
; <label>:115: ; preds = %111, %115
%116 = phi i8* [ %118, %115 ], [ %97, %111 ]
%117 = phi i8* [ %119, %115 ], [ %11, %111 ]
%118 = getelementptr inbounds i8, i8* %116, i32 -1
%119 = getelementptr inbounds i8, i8* %117, i32 -1
%120 = load i8, i8* %119, align 1
store i8 %120, i8* %118, align 1
%121 = icmp eq i8* %119, %113
br i1 %121, label %122, label %115
; <label>:122: ; preds = %115
%123 = ptrtoint i8* %118 to i32
br label %124
; <label>:124: ; preds = %122, %111
%125 = phi i32 [ %98, %111 ], [ %123, %122 ]
%126 = phi i8* [ %97, %111 ], [ %118, %122 ]
%127 = load i8*, i8** %22, align 4
%128 = icmp eq i8* %127, %11
br i1 %128, label %129, label %131
; <label>:129: ; preds = %124
%130 = ptrtoint i8* %126 to i32
br label %142
; <label>:131: ; preds = %124
%132 = inttoptr i32 %112 to i8*
br label %133
; <label>:133: ; preds = %133, %131
%134 = phi i8* [ %138, %133 ], [ %132, %131 ]
%135 = phi i8* [ %137, %133 ], [ %11, %131 ]
%136 = load i8, i8* %135, align 1
store i8 %136, i8* %134, align 1
%137 = getelementptr inbounds i8, i8* %135, i32 1
%138 = getelementptr inbounds i8, i8* %134, i32 1
%139 = icmp eq i8* %137, %127
br i1 %139, label %140, label %133
; <label>:140: ; preds = %133
%141 = ptrtoint i8* %138 to i32
br label %142
; <label>:142: ; preds = %140, %129
%143 = phi i32 [ %112, %129 ], [ %141, %140 ]
%144 = phi i32 [ %130, %129 ], [ %125, %140 ]
%145 = load i8*, i8** %6, align 4
store i32 %144, i32* %8, align 4
store i32 %143, i32* %27, align 4
store i32 %100, i32* %20, align 4
%146 = icmp eq i8* %145, null
br i1 %146, label %148, label %147
; <label>:147: ; preds = %142
tail call void @Free(i8* nonnull %145) #13
br label %148
; <label>:148: ; preds = %16, %147, %142, %43, %71, %75
%149 = phi i32 [ %17, %16 ], [ %98, %147 ], [ %98, %142 ], [ %29, %43 ], [ %29, %71 ], [ %29, %75 ]
ret i32 %149
}

View File

@ -75,8 +75,8 @@ for.body.2: ; preds = %for.body.1
for.body.3: ; preds = %for.body.2
; CHECK: %for.body.3
; CHECK: ldrb {{r[0-9]+|lr}}, [{{r[0-9]+|lr}}, {{r[0-9]+|lr}}]!
; CHECK: ldrb {{r[0-9]+|lr}}, [{{r[0-9]+|lr}}, {{r[0-9]+|lr}}]!
; CHECK: ldrb {{r[0-9]+|lr}}, [{{r[0-9]+|lr}}, {{r[0-9]+|lr}}]
; CHECK: ldrb {{r[0-9]+|lr}}, [{{r[0-9]+|lr}}, {{r[0-9]+|lr}}]
%arrayidx.3 = getelementptr inbounds i8, i8* %a, i32 %add5.2
%6 = load i8, i8* %arrayidx.3, align 1
%conv6.3 = zext i8 %6 to i32

View File

@ -8,22 +8,20 @@ define void @f(i8*, i8*, i64*) {
; CHECK-NEXT: cmpld 3, 4
; CHECK-NEXT: beqlr 0
; CHECK-NEXT: # %bb.1:
; CHECK-NEXT: ld 6, 8(5)
; CHECK-NEXT: not 3, 3
; CHECK-NEXT: add 3, 3, 4
; CHECK-NEXT: li 4, 0
; CHECK-NEXT: .p2align 5
; CHECK-NEXT: li 4, 15
; CHECK-NEXT: cmpldi 3, 15
; CHECK-NEXT: isellt 3, 3, 4
; CHECK-NEXT: addi 4, 3, 1
; CHECK-NEXT: ld 3, 8(5)
; CHECK-NEXT: mtctr 4
; CHECK-NEXT: .p2align 4
; CHECK-NEXT: .LBB0_2:
; CHECK-NEXT: addi 7, 4, 1
; CHECK-NEXT: sldi 6, 6, 4
; CHECK-NEXT: cmplwi 4, 14
; CHECK-NEXT: bc 12, 1, .LBB0_4
; CHECK-NEXT: sldi 3, 3, 4
; CHECK-NEXT: bdnz .LBB0_2
; CHECK-NEXT: # %bb.3:
; CHECK-NEXT: cmpd 3, 4
; CHECK-NEXT: mr 4, 7
; CHECK-NEXT: bc 4, 2, .LBB0_2
; CHECK-NEXT: .LBB0_4:
; CHECK-NEXT: std 6, 8(5)
; CHECK-NEXT: std 3, 8(5)
; CHECK-NEXT: blr
%4 = icmp eq i8* %0, %1

View File

@ -27,7 +27,7 @@
; CHECK-NEXT: JCC_1 {{.*}}, debug-location [[DLOC]]{{$}}
; CHECK: [[VREG3:%[^ ]+]]:gr64 = PHI [[VREG2]]
; CHECK: [[VREG4:%[^ ]+]]:gr64 = nuw ADD64ri8 [[VREG3]], 4
; CHECK: SUB64rr [[VREG1]], [[VREG4]]
; CHECK: SUB64rr [[VREG4]], [[VREG1]]
; CHECK-NEXT: JCC_1 {{.*}}, debug-location [[DLOC]]{{$}}
; CHECK-NEXT: JMP_1 {{.*}}, debug-location [[DLOC]]{{$}}

View File

@ -12,19 +12,16 @@ define amdgpu_kernel void @local_cmp_user(i32 %arg0) nounwind {
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[ARG0:%.*]], 1
; CHECK-NEXT: br label [[BB11:%.*]]
; CHECK: bb11:
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i32 [ [[LSR_IV_NEXT3:%.*]], [[BB:%.*]] ], [ -2, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i32 [ [[LSR_IV_NEXT2:%.*]], [[BB:%.*]] ], [ -2, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[BB]] ], [ [[TMP0]], [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV_NEXT]] = add i32 [[LSR_IV]], -1
; CHECK-NEXT: [[LSR_IV_NEXT3]] = add i32 [[LSR_IV2]], 2
; CHECK-NEXT: [[LSR_IV_NEXT2]] = add i32 [[LSR_IV1]], 2
; CHECK-NEXT: [[C0:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[C0]], label [[BB13:%.*]], label [[BB]]
; CHECK: bb:
; CHECK-NEXT: [[T:%.*]] = load i8 addrspace(3)*, i8 addrspace(3)* addrspace(3)* undef, align 4
; CHECK-NEXT: [[T1:%.*]] = ptrtoint i8 addrspace(3)* [[T]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 0, [[T1]]
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i32 [[TMP1]] to i8 addrspace(3)*
; CHECK-NEXT: [[TMP:%.*]] = inttoptr i32 [[LSR_IV_NEXT3]] to i8 addrspace(3)*
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 addrspace(3)* [[TMP2]], [[TMP]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8 addrspace(3)* [[T]], i32 [[LSR_IV_NEXT2]]
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 addrspace(3)* [[SCEVGEP]], null
; CHECK-NEXT: br i1 [[C1]], label [[BB11]], label [[BB13]]
; CHECK: bb13:
; CHECK-NEXT: unreachable
@ -55,19 +52,16 @@ define amdgpu_kernel void @global_cmp_user(i64 %arg0) nounwind {
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[ARG0:%.*]], 1
; CHECK-NEXT: br label [[BB11:%.*]]
; CHECK: bb11:
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i64 [ [[LSR_IV_NEXT3:%.*]], [[BB:%.*]] ], [ -2, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i64 [ [[LSR_IV_NEXT2:%.*]], [[BB:%.*]] ], [ -2, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[BB]] ], [ [[TMP0]], [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -1
; CHECK-NEXT: [[LSR_IV_NEXT3]] = add i64 [[LSR_IV2]], 2
; CHECK-NEXT: [[LSR_IV_NEXT2]] = add i64 [[LSR_IV1]], 2
; CHECK-NEXT: [[C0:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[C0]], label [[BB13:%.*]], label [[BB]]
; CHECK: bb:
; CHECK-NEXT: [[T:%.*]] = load i8 addrspace(1)*, i8 addrspace(1)* addrspace(1)* undef, align 8
; CHECK-NEXT: [[T1:%.*]] = ptrtoint i8 addrspace(1)* [[T]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[T1]]
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to i8 addrspace(1)*
; CHECK-NEXT: [[TMP:%.*]] = inttoptr i64 [[LSR_IV_NEXT3]] to i8 addrspace(1)*
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 addrspace(1)* [[TMP2]], [[TMP]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8 addrspace(1)* [[T]], i64 [[LSR_IV_NEXT2]]
; CHECK-NEXT: [[C1:%.*]] = icmp ne i8 addrspace(1)* [[SCEVGEP]], null
; CHECK-NEXT: br i1 [[C1]], label [[BB11]], label [[BB13]]
; CHECK: bb13:
; CHECK-NEXT: unreachable

View File

@ -10,22 +10,19 @@ declare void @use1(i1)
define void @is_not_42(i8* %baseptr, i8* %finalptr) local_unnamed_addr align 2 personality i8* undef {
; CHECK-LABEL: @is_not_42(
; CHECK-NEXT: preheader:
; CHECK-NEXT: [[BASEPTR1:%.*]] = ptrtoint i8* [[BASEPTR:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[BASEPTR1]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* inttoptr (i64 42 to i8*), i64 [[TMP0]]
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[LATCH:%.*]] ], [ [[SCEVGEP]], [[PREHEADER:%.*]] ]
; CHECK-NEXT: [[PTR:%.*]] = phi i8* [ [[INCPTR:%.*]], [[LATCH:%.*]] ], [ [[BASEPTR:%.*]], [[PREHEADER:%.*]] ]
; CHECK-NEXT: invoke void @maybe_throws()
; CHECK-NEXT: to label [[LATCH]] unwind label [[LPAD:%.*]]
; CHECK: lpad:
; CHECK-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: catch i8* inttoptr (i64 42 to i8*)
; CHECK-NEXT: [[PTR_IS_NOT_42:%.*]] = icmp ne i8* [[LSR_IV]], null
; CHECK-NEXT: [[PTR_IS_NOT_42:%.*]] = icmp ne i8* [[PTR]], inttoptr (i64 42 to i8*)
; CHECK-NEXT: call void @use1(i1 [[PTR_IS_NOT_42]])
; CHECK-NEXT: ret void
; CHECK: latch:
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i64 -1
; CHECK-NEXT: [[INCPTR]] = getelementptr inbounds i8, i8* [[PTR]], i64 1
; CHECK-NEXT: br label [[HEADER]]
;
preheader:

View File

@ -10,22 +10,19 @@ declare void @use1(i1)
define void @is_not_null(i8* %baseptr) local_unnamed_addr align 2 personality i8* undef {
; CHECK-LABEL: @is_not_null(
; CHECK-NEXT: preheader:
; CHECK-NEXT: [[BASEPTR1:%.*]] = ptrtoint i8* [[BASEPTR:%.*]] to i64
; CHECK-NEXT: [[TMP0:%.*]] = sub i64 0, [[BASEPTR1]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* null, i64 [[TMP0]]
; CHECK-NEXT: br label [[HEADER:%.*]]
; CHECK: header:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[LATCH:%.*]] ], [ [[SCEVGEP]], [[PREHEADER:%.*]] ]
; CHECK-NEXT: [[PTR:%.*]] = phi i8* [ [[INCPTR:%.*]], [[LATCH:%.*]] ], [ [[BASEPTR:%.*]], [[PREHEADER:%.*]] ]
; CHECK-NEXT: invoke void @maybe_throws()
; CHECK-NEXT: to label [[LATCH]] unwind label [[LPAD:%.*]]
; CHECK: lpad:
; CHECK-NEXT: [[TMP1:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 }
; CHECK-NEXT: catch i8* null
; CHECK-NEXT: [[PTR_IS_NOT_NULL:%.*]] = icmp ne i8* [[LSR_IV]], null
; CHECK-NEXT: [[PTR_IS_NOT_NULL:%.*]] = icmp ne i8* [[PTR]], null
; CHECK-NEXT: call void @use1(i1 [[PTR_IS_NOT_NULL]])
; CHECK-NEXT: ret void
; CHECK: latch:
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i64 -1
; CHECK-NEXT: [[INCPTR]] = getelementptr inbounds i8, i8* [[PTR]], i64 1
; CHECK-NEXT: br label [[HEADER]]
;
preheader:

View File

@ -11,42 +11,33 @@ target triple = "x86_64-apple-macosx10.15.0"
define i64 @blam(%struct.hoge* %start, %struct.hoge* %end, %struct.hoge* %ptr.2) {
; CHECK-LABEL: @blam(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[START9:%.*]] = ptrtoint %struct.hoge* [[START:%.*]] to i64
; CHECK-NEXT: [[START6:%.*]] = bitcast %struct.hoge* [[START]] to i8*
; CHECK-NEXT: [[END8:%.*]] = bitcast %struct.hoge* [[END:%.*]] to i8*
; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint %struct.hoge* [[START]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 0, [[START9]]
; CHECK-NEXT: [[UGLYGEP10:%.*]] = getelementptr i8, i8* [[END8]], i64 [[TMP1]]
; CHECK-NEXT: [[START1:%.*]] = ptrtoint %struct.hoge* [[START:%.*]] to i64
; CHECK-NEXT: br label [[LOOP_1_HEADER:%.*]]
; CHECK: loop.1.header:
; CHECK-NEXT: [[LSR_IV4:%.*]] = phi i64 [ [[LSR_IV_NEXT5:%.*]], [[LOOP_1_HEADER]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV_NEXT5]] = add i64 [[LSR_IV4]], -16
; CHECK-NEXT: [[SCEVGEP11:%.*]] = getelementptr i8, i8* [[UGLYGEP10]], i64 [[LSR_IV_NEXT5]]
; CHECK-NEXT: [[SCEVGEP1112:%.*]] = bitcast i8* [[SCEVGEP11]] to %struct.hoge*
; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[SCEVGEP1112]], null
; CHECK-NEXT: [[LSR_IV5:%.*]] = phi i64 [ [[LSR_IV_NEXT6:%.*]], [[LOOP_1_HEADER]] ], [ [[START1]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[IV:%.*]] = phi %struct.hoge* [ [[IV_NEXT:%.*]], [[LOOP_1_HEADER]] ], [ [[START]], [[ENTRY]] ]
; CHECK-NEXT: [[IV_NEXT]] = getelementptr inbounds [[STRUCT_HOGE:%.*]], %struct.hoge* [[IV]], i64 1
; CHECK-NEXT: [[LSR_IV_NEXT6]] = add nuw i64 [[LSR_IV5]], 16
; CHECK-NEXT: [[EC:%.*]] = icmp eq %struct.hoge* [[IV_NEXT]], [[END:%.*]]
; CHECK-NEXT: br i1 [[EC]], label [[LOOP_2_PH:%.*]], label [[LOOP_1_HEADER]]
; CHECK: loop.2.ph:
; CHECK-NEXT: [[TMP2:%.*]] = sub i64 [[TMP0]], [[LSR_IV_NEXT5]]
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[LSR_IV_NEXT5]], -1
; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[START6]], i64 [[TMP3]]
; CHECK-NEXT: [[UGLYGEP7:%.*]] = bitcast i8* [[UGLYGEP]] to %struct.hoge*
; CHECK-NEXT: br label [[LOOP_2_HEADER:%.*]]
; CHECK: loop.2.header:
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi i64 [ [[LSR_IV_NEXT2:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[TMP2]], [[LOOP_2_PH]] ]
; CHECK-NEXT: [[IV2:%.*]] = phi %struct.hoge* [ [[IV2_NEXT:%.*]], [[LOOP_2_LATCH]] ], [ [[UGLYGEP7]], [[LOOP_2_PH]] ]
; CHECK-NEXT: [[IV23:%.*]] = bitcast %struct.hoge* [[IV2]] to i32*
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[LSR_IV1]], 12
; CHECK-NEXT: call void @use.i64(i64 [[TMP4]])
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[IV23]], i64 2
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi i64 [ [[LSR_IV_NEXT3:%.*]], [[LOOP_2_LATCH:%.*]] ], [ [[LSR_IV_NEXT6]], [[LOOP_2_PH]] ]
; CHECK-NEXT: [[IV2:%.*]] = phi %struct.hoge* [ [[IV2_NEXT:%.*]], [[LOOP_2_LATCH]] ], [ [[IV_NEXT]], [[LOOP_2_PH]] ]
; CHECK-NEXT: [[IV24:%.*]] = bitcast %struct.hoge* [[IV2]] to i32*
; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[LSR_IV2]], 12
; CHECK-NEXT: call void @use.i64(i64 [[TMP0]])
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i32, i32* [[IV24]], i64 2
; CHECK-NEXT: store i32 10, i32* [[SCEVGEP]], align 8
; CHECK-NEXT: [[EC_2:%.*]] = icmp ugt %struct.hoge* [[IV2]], [[PTR_2:%.*]]
; CHECK-NEXT: br i1 [[EC_2]], label [[LOOP_2_EXIT:%.*]], label [[LOOP_2_LATCH]]
; CHECK: loop.2.latch:
; CHECK-NEXT: [[IV2_NEXT]] = getelementptr inbounds [[STRUCT_HOGE:%.*]], %struct.hoge* [[IV2]], i64 1
; CHECK-NEXT: [[LSR_IV_NEXT2]] = add i64 [[LSR_IV1]], 16
; CHECK-NEXT: [[IV2_NEXT]] = getelementptr inbounds [[STRUCT_HOGE]], %struct.hoge* [[IV2]], i64 1
; CHECK-NEXT: [[LSR_IV_NEXT3]] = add i64 [[LSR_IV2]], 16
; CHECK-NEXT: br label [[LOOP_2_HEADER]]
; CHECK: loop.2.exit:
; CHECK-NEXT: ret i64 [[LSR_IV1]]
; CHECK-NEXT: ret i64 [[LSR_IV2]]
;
entry:
br label %loop.1.header

View File

@ -25,7 +25,7 @@ define void @test(double* %ioptr, i32 %X, double* %start, double* %end) {
; CHECK-NEXT: [[UGLYGEP2:%.*]] = bitcast i8* [[UGLYGEP]] to double*
; CHECK-NEXT: [[F1I_0:%.*]] = load double, double* [[UGLYGEP2]], align 8
; CHECK-NEXT: call void @use(double [[F1I_0]])
; CHECK-NEXT: [[EC0:%.*]] = icmp eq double* [[END:%.*]], [[ADD_PTR94]]
; CHECK-NEXT: [[EC0:%.*]] = icmp eq double* [[ADD_PTR94]], [[END:%.*]]
; CHECK-NEXT: br i1 [[EC0]], label [[FOR_BODY37]], label [[FOR_END_LOOPEXIT:%.*]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label [[FOR_END:%.*]]

View File

@ -110,7 +110,7 @@ define i32 @user(i32* %a, i32* %b, i32 %x) nounwind {
; X64-NEXT: addl (%rdi,%r8), %eax
; X64-NEXT: movl %eax, (%rdi)
; X64-NEXT: addq %rdx, %rdi
; X64-NEXT: cmpq %rdi, %rsi
; X64-NEXT: cmpq %rsi, %rdi
; X64-NEXT: jne .LBB1_1
; X64-NEXT: # %bb.2: # %exit
; X64-NEXT: retq
@ -137,7 +137,7 @@ define i32 @user(i32* %a, i32* %b, i32 %x) nounwind {
; X32-NEXT: addl (%esi,%ebx), %eax
; X32-NEXT: movl %eax, (%esi)
; X32-NEXT: addl %edi, %esi
; X32-NEXT: cmpl %esi, %edx
; X32-NEXT: cmpl %edx, %esi
; X32-NEXT: jne .LBB1_1
; X32-NEXT: # %bb.2: # %exit
; X32-NEXT: popl %esi

View File

@ -26,14 +26,12 @@ define void @f() personality i32 (...)* @_except_handler3 {
; CHECK-NEXT: unreachable
; CHECK: blah2:
; CHECK-NEXT: [[CLEANUPPADI4_I_I_I:%.*]] = cleanuppad within none []
; CHECK-NEXT: [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 1, [[PHI21]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PHI2]], i32 -1
; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
; CHECK: loop_body:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH2]] ]
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP1:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH2]] ]
; CHECK-NEXT: [[SCEVGEP1]] = getelementptr i8, i8* [[LSR_IV]], i32 1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP1]], undef
; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
; CHECK: iter:
; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
@ -89,18 +87,16 @@ define void @g() personality i32 (...)* @_except_handler3 {
; CHECK-NEXT: unreachable
; CHECK: blah:
; CHECK-NEXT: [[CATCHPAD:%.*]] = catchpad within [[CS]] []
; CHECK-NEXT: [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 1, [[PHI21]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PHI2]], i32 -1
; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
; CHECK: unwind_out:
; CHECK-NEXT: catchret from [[CATCHPAD]] to label [[LEAVE:%.*]]
; CHECK: leave:
; CHECK-NEXT: ret void
; CHECK: loop_body:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH:%.*]] ]
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP1:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH:%.*]] ]
; CHECK-NEXT: [[SCEVGEP1]] = getelementptr i8, i8* [[LSR_IV]], i32 1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP1]], undef
; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
; CHECK: iter:
; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
@ -157,18 +153,16 @@ define void @h() personality i32 (...)* @_except_handler3 {
; CHECK: blug:
; CHECK-NEXT: [[PHI2:%.*]] = phi i8* [ [[TMP96]], [[PAD]] ]
; CHECK-NEXT: [[CATCHPAD:%.*]] = catchpad within [[CS]] []
; CHECK-NEXT: [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
; CHECK-NEXT: [[TMP1:%.*]] = sub i32 1, [[PHI21]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PHI2]], i32 -1
; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
; CHECK: unwind_out:
; CHECK-NEXT: catchret from [[CATCHPAD]] to label [[LEAVE:%.*]]
; CHECK: leave:
; CHECK-NEXT: ret void
; CHECK: loop_body:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLUG:%.*]] ]
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP1:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLUG:%.*]] ]
; CHECK-NEXT: [[SCEVGEP1]] = getelementptr i8, i8* [[LSR_IV]], i32 1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP1]], undef
; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
; CHECK: iter:
; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
@ -227,14 +221,12 @@ define void @i() personality i32 (...)* @_except_handler3 {
; CHECK-NEXT: [[TMP1:%.*]] = cleanuppad within none []
; CHECK-NEXT: br label [[LOOP_HEAD]]
; CHECK: loop_head:
; CHECK-NEXT: [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
; CHECK-NEXT: [[TMP2:%.*]] = sub i32 1, [[PHI21]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP2]]
; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PHI2]], i32 -1
; CHECK-NEXT: br label [[LOOP_BODY:%.*]]
; CHECK: loop_body:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[LOOP_HEAD]] ]
; CHECK-NEXT: [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP1:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[LOOP_HEAD]] ]
; CHECK-NEXT: [[SCEVGEP1]] = getelementptr i8, i8* [[LSR_IV]], i32 1
; CHECK-NEXT: [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP1]], undef
; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
; CHECK: iter:
; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]

View File

@ -14,30 +14,29 @@ define void @b_copy_ctor() personality i32 (...)* @__CxxFrameHandler3 {
; CHECK-LABEL: @b_copy_ctor(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load %struct.L*, %struct.L** @GV1, align 8
; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint %struct.L* [[TMP0]] to i64
; CHECK-NEXT: [[TMP1:%.*]] = bitcast %struct.L* [[TMP0]] to i8*
; CHECK-NEXT: br label [[FOR_COND:%.*]]
; CHECK: for.cond:
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[CALL_I_NOEXC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
; CHECK-NEXT: [[TMP:%.*]] = inttoptr i64 [[LSR_IV]] to %struct.L*
; CHECK-NEXT: [[LSR_IV2:%.*]] = inttoptr i64 [[LSR_IV]] to %struct.L*
; CHECK-NEXT: invoke void @a_copy_ctor()
; CHECK-NEXT: to label [[CALL_I_NOEXC]] unwind label [[CATCH_DISPATCH:%.*]]
; CHECK: call.i.noexc:
; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], 16
; CHECK-NEXT: [[LSR_IV_NEXT]] = add i64 [[LSR_IV]], -16
; CHECK-NEXT: br label [[FOR_COND]]
; CHECK: catch.dispatch:
; CHECK-NEXT: [[TMP2:%.*]] = catchswitch within none [label %catch] unwind to caller
; CHECK: catch:
; CHECK-NEXT: [[TMP3:%.*]] = catchpad within [[TMP2]] [i8* null, i32 64, i8* null]
; CHECK-NEXT: [[CMP16:%.*]] = icmp eq %struct.L* [[TMP]], null
; CHECK-NEXT: [[TMP4:%.*]] = sub i64 0, [[TMP1]]
; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* getelementptr inbounds (%struct.L, %struct.L* @GV2, i32 0, i32 0), i64 [[TMP4]]
; CHECK-NEXT: [[CMP16:%.*]] = icmp eq %struct.L* [[LSR_IV2]], null
; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[LSR_IV]], -1
; CHECK-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, i8* [[TMP1]], i64 [[TMP4]]
; CHECK-NEXT: [[UGLYGEP1:%.*]] = bitcast i8* [[UGLYGEP]] to %struct.L*
; CHECK-NEXT: br i1 [[CMP16]], label [[FOR_END:%.*]], label [[FOR_BODY_PREHEADER:%.*]]
; CHECK: for.body.preheader:
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[TMP5:%.*]] = inttoptr i64 [[LSR_IV]] to %struct.L*
; CHECK-NEXT: [[CMP:%.*]] = icmp eq %struct.L* [[UGLYGEP1]], [[TMP5]]
; CHECK-NEXT: [[CMP:%.*]] = icmp eq %struct.L* [[UGLYGEP1]], @GV2
; CHECK-NEXT: br i1 [[CMP]], label [[FOR_END_LOOPEXIT:%.*]], label [[FOR_BODY]]
; CHECK: for.end.loopexit:
; CHECK-NEXT: br label [[FOR_END]]