[llvm] r317911 - [CVP] Remove some {s|u}add.with.overflow checks.

Sanjoy Das via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 11 19:28:00 PST 2017


+CC Joel

On Fri, Nov 10, 2017 at 11:42 AM, Davide Italiano <davide at freebsd.org> wrote:
> On Fri, Nov 10, 2017 at 11:13 AM, Sanjoy Das via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>> Author: sanjoy
>> Date: Fri Nov 10 11:13:35 2017
>> New Revision: 317911
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=317911&view=rev
>> Log:
>> [CVP] Remove some {s|u}add.with.overflow checks.
>>
>> Summary:
>> This adds logic to CVP to remove some overflow checks.  It uses LVI to remove
>> operations with at least one constant.  Specifically, this can remove many
>> overflow intrinsics immediately following an overflow check in the source code,
>> such as:
>>
>> if (x < INT_MAX)
>>     ... x + 1 ...
>>
>> Patch by Joel Galenson!
>>
>> Reviewers: sanjoy, regehr
>>
>> Reviewed By: sanjoy
>>
>> Subscribers: fhahn, pirama, srhines, llvm-commits
>>
>> Differential Revision: https://reviews.llvm.org/D39483
>>
>> Added:
>>     llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll
>> Modified:
>>     llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>>
>> Modified: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp?rev=317911&r1=317910&r2=317911&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp (original)
>> +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp Fri Nov 10 11:13:35 2017
>> @@ -31,6 +31,8 @@
>>  #include "llvm/IR/InstrTypes.h"
>>  #include "llvm/IR/Instruction.h"
>>  #include "llvm/IR/Instructions.h"
>> +#include "llvm/IR/IntrinsicInst.h"
>> +#include "llvm/IR/IRBuilder.h"
>>  #include "llvm/IR/Operator.h"
>>  #include "llvm/IR/PassManager.h"
>>  #include "llvm/IR/Type.h"
>> @@ -58,6 +60,7 @@ STATISTIC(NumDeadCases, "Number of switc
>>  STATISTIC(NumSDivs,     "Number of sdiv converted to udiv");
>>  STATISTIC(NumAShrs,     "Number of ashr converted to lshr");
>>  STATISTIC(NumSRems,     "Number of srem converted to urem");
>> +STATISTIC(NumOverflows, "Number of overflow checks removed");
>>
>>  static cl::opt<bool> DontProcessAdds("cvp-dont-process-adds", cl::init(true));
>>
>> @@ -323,11 +326,63 @@ static bool processSwitch(SwitchInst *SI
>>    return Changed;
>>  }
>>
>> +// See if we can prove that the given overflow intrinsic will not overflow.
>> +static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) {
>> +  using OBO = OverflowingBinaryOperator;
>> +  auto NoWrapOnAddition = [&] (Value *LHS, Value *RHS, unsigned NoWrapKind) {
>> +    ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II);
>> +    ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
>> +        BinaryOperator::Add, RRange, NoWrapKind);
>> +    // As an optimization, do not compute LRange if we do not need it.
>> +    if (NWRegion.isEmptySet())
>> +      return false;
>> +    ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II);
>> +    return NWRegion.contains(LRange);
>> +  };
>> +  switch (II->getIntrinsicID()) {
>> +  default:
>> +    break;
>> +  case Intrinsic::uadd_with_overflow:
>> +    return NoWrapOnAddition(II->getOperand(0), II->getOperand(1),
>> +                            OBO::NoUnsignedWrap);
>> +  case Intrinsic::sadd_with_overflow:
>> +    return NoWrapOnAddition(II->getOperand(0), II->getOperand(1),
>> +                            OBO::NoSignedWrap);
>> +  }
>> +  return false;
>> +}
>> +
>> +static void processOverflowIntrinsic(IntrinsicInst *II) {
>> +  Value *NewOp = nullptr;
>> +  switch (II->getIntrinsicID()) {
>> +  default:
>> +    llvm_unreachable("Illegal instruction.");
>> +  case Intrinsic::uadd_with_overflow:
>> +  case Intrinsic::sadd_with_overflow:
>> +    NewOp = BinaryOperator::CreateAdd(II->getOperand(0), II->getOperand(1),
>> +                                      II->getName(), II);
>> +    break;
>> +  }
>> +  ++NumOverflows;
>> +  IRBuilder<> B(II);
>> +  Value *NewI = B.CreateInsertValue(UndefValue::get(II->getType()), NewOp, 0);
>> +  NewI = B.CreateInsertValue(NewI, ConstantInt::getFalse(II->getContext()), 1);
>> +  II->replaceAllUsesWith(NewI);
>> +  II->eraseFromParent();
>> +}
>> +
>>  /// Infer nonnull attributes for the arguments at the specified callsite.
>>  static bool processCallSite(CallSite CS, LazyValueInfo *LVI) {
>>    SmallVector<unsigned, 4> ArgNos;
>>    unsigned ArgNo = 0;
>>
>> +  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) {
>
> Nit: auto * maybe?
>
>> +    if (willNotOverflow(II, LVI)) {
>> +      processOverflowIntrinsic(II);
>> +      return true;
>> +    }
>> +  }
>> +
>>    for (Value *V : CS.args()) {
>>      PointerType *Type = dyn_cast<PointerType>(V->getType());
>>      // Try to mark pointer typed parameters as non-null.  We skip the
>>
>> Added: llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll?rev=317911&view=auto
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll (added)
>> +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll Fri Nov 10 11:13:35 2017
>> @@ -0,0 +1,369 @@
>> +; RUN: opt -S -correlated-propagation < %s | FileCheck %s
>> +
>> +declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
>> +
>> +declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
>> +
>> +declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
>> +
>> +declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
>> +
>> +declare void @llvm.trap()
>> +
>> +
>> +define i32 @signed_add(i32 %x, i32 %y) {
>> +; CHECK-LABEL: @signed_add(
>> +; CHECK: @llvm.ssub.with.overflow.i32
>> +; CHECK: @llvm.ssub.with.overflow.i32
>> +; CHECK: @llvm.sadd.with.overflow.i32
>> +entry:
>> +  %cmp = icmp sgt i32 %y, 0
>> +  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
>> +
>> +land.lhs.true:                                    ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 2147483647, i32 %y)
>> +  %1 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %1, label %trap, label %cont
>> +
>> +trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cont:                                             ; preds = %land.lhs.true
>> +  %2 = extractvalue { i32, i1 } %0, 0
>> +  %cmp1 = icmp slt i32 %2, %x
>> +  br i1 %cmp1, label %cond.end, label %cond.false
>> +
>> +lor.lhs.false:                                    ; preds = %entry
>> +  %cmp2 = icmp slt i32 %y, 0
>> +  br i1 %cmp2, label %land.lhs.true3, label %cond.false
>> +
>> +land.lhs.true3:                                   ; preds = %lor.lhs.false
>> +  %3 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 -2147483648, i32 %y)
>> +  %4 = extractvalue { i32, i1 } %3, 1
>> +  br i1 %4, label %trap, label %cont4
>> +
>> +cont4:                                            ; preds = %land.lhs.true3
>> +  %5 = extractvalue { i32, i1 } %3, 0
>> +  %cmp5 = icmp sgt i32 %5, %x
>> +  br i1 %cmp5, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %cont, %cont4, %lor.lhs.false
>> +  %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 %y)
>> +  %7 = extractvalue { i32, i1 } %6, 0
>> +  %8 = extractvalue { i32, i1 } %6, 1
>> +  br i1 %8, label %trap, label %cond.end
>> +
>> +cond.end:                                         ; preds = %cond.false, %cont, %cont4
>> +  %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @unsigned_add(i32 %x, i32 %y) {
>> +; CHECK-LABEL: @unsigned_add(
>> +; CHECK: @llvm.usub.with.overflow.i32
>> +; CHECK: @llvm.uadd.with.overflow.i32
>> +entry:
>> +  %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y)
>> +  %1 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %1, label %trap, label %cont
>> +
>> +trap:                                             ; preds = %cond.false, %entry
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cont:                                             ; preds = %entry
>> +  %2 = extractvalue { i32, i1 } %0, 0
>> +  %cmp1 = icmp ult i32 %2, %x
>> +  br i1 %cmp1, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %cont
>> +  %3 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
>> +  %4 = extractvalue { i32, i1 } %3, 0
>> +  %5 = extractvalue { i32, i1 } %3, 1
>> +  br i1 %5, label %trap, label %cond.end
>> +
>> +cond.end:                                         ; preds = %cond.false, %cont
>> +  %cond = phi i32 [ 0, %cont ], [ %4, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @signed_sub(i32 %x, i32 %y) {
>> +; CHECK-LABEL: @signed_sub(
>> +; CHECK-NOT: @llvm.sadd.with.overflow.i32
>> +; CHECK: @llvm.ssub.with.overflow.i32
>> +entry:
>> +  %cmp = icmp slt i32 %y, 0
>> +  br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
>> +
>> +land.lhs.true:                                    ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 2147483647)
>> +  %1 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %1, label %trap, label %cont
>> +
>> +trap:                                             ; preds = %land.lhs.true, %land.lhs.true3, %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cont:                                             ; preds = %land.lhs.true
>> +  %2 = extractvalue { i32, i1 } %0, 0
>> +  %cmp1 = icmp slt i32 %2, %x
>> +  br i1 %cmp1, label %cond.end, label %cond.false
>> +
>> +lor.lhs.false:                                    ; preds = %entry
>> +  %cmp2 = icmp eq i32 %y, 0
>> +  br i1 %cmp2, label %cond.false, label %land.lhs.true3
>> +
>> +land.lhs.true3:                                   ; preds = %lor.lhs.false
>> +  %3 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %y, i32 -2147483648)
>> +  %4 = extractvalue { i32, i1 } %3, 1
>> +  br i1 %4, label %trap, label %cont4
>> +
>> +cont4:                                            ; preds = %land.lhs.true3
>> +  %5 = extractvalue { i32, i1 } %3, 0
>> +  %cmp5 = icmp sgt i32 %5, %x
>> +  br i1 %cmp5, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %lor.lhs.false, %cont, %cont4
>> +  %6 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 %y)
>> +  %7 = extractvalue { i32, i1 } %6, 0
>> +  %8 = extractvalue { i32, i1 } %6, 1
>> +  br i1 %8, label %trap, label %cond.end
>> +
>> +cond.end:                                         ; preds = %cond.false, %cont, %cont4
>> +  %cond = phi i32 [ 0, %cont4 ], [ 0, %cont ], [ %7, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @unsigned_sub(i32 %x, i32 %y) {
>> +; CHECK-LABEL: @unsigned_sub(
>> +; CHECK: @llvm.usub.with.overflow.i32
>> +entry:
>> +  %cmp = icmp ult i32 %x, %y
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 %y)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @signed_add_r1(i32 %x) {
>> +; CHECK-LABEL: @signed_add_r1(
>> +; CHECK-NOT: @llvm.sadd.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, 2147483647
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @unsigned_add_r1(i32 %x) {
>> +; CHECK-LABEL: @unsigned_add_r1(
>> +; CHECK-NOT: @llvm.uadd.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, -1
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %x, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @signed_sub_r1(i32 %x) {
>> +; CHECK-LABEL: @signed_sub_r1(
>> +; CHECK: @llvm.ssub.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, -2147483648
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @unsigned_sub_r1(i32 %x) {
>> +; CHECK-LABEL: @unsigned_sub_r1(
>> +; CHECK: @llvm.usub.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, 0
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %x, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @signed_add_rn1(i32 %x) {
>> +; CHECK-LABEL: @signed_add_rn1(
>> +; CHECK-NOT: @llvm.sadd.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, -2147483648
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %x, i32 -1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +define i32 @signed_sub_rn1(i32 %x) {
>> +; CHECK-LABEL: @signed_sub_rn1(
>> +; CHECK: @llvm.ssub.with.overflow.i32
>> +entry:
>> +  %cmp = icmp eq i32 %x, 2147483647
>> +  br i1 %cmp, label %cond.end, label %cond.false
>> +
>> +cond.false:                                       ; preds = %entry
>> +  %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %x, i32 -1)
>> +  %1 = extractvalue { i32, i1 } %0, 0
>> +  %2 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %2, label %trap, label %cond.end
>> +
>> +trap:                                             ; preds = %cond.false
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cond.end:                                         ; preds = %cond.false, %entry
>> +  %cond = phi i32 [ 0, %entry ], [ %1, %cond.false ]
>> +  ret i32 %cond
>> +}
>> +
>> +declare i32 @bar(i32)
>> +
>> +define void @unsigned_loop(i32 %i) {
>> +; CHECK-LABEL: @unsigned_loop(
>> +; CHECK: @llvm.usub.with.overflow.i32
>> +entry:
>> +  %cmp3 = icmp eq i32 %i, 0
>> +  br i1 %cmp3, label %while.end, label %while.body.preheader
>> +
>> +while.body.preheader:                             ; preds = %entry
>> +  br label %while.body
>> +
>> +while.body:                                       ; preds = %while.body.preheader, %cont
>> +  %i.addr.04 = phi i32 [ %2, %cont ], [ %i, %while.body.preheader ]
>> +  %call = tail call i32 @bar(i32 %i.addr.04)
>> +  %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.addr.04, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %1, label %trap, label %cont
>> +
>> +trap:                                             ; preds = %while.body
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cont:                                             ; preds = %while.body
>> +  %2 = extractvalue { i32, i1 } %0, 0
>> +  %cmp = icmp eq i32 %2, 0
>> +  br i1 %cmp, label %while.end, label %while.body
>> +
>> +while.end:                                        ; preds = %cont, %entry
>> +  ret void
>> +}
>> +
>> +define void @intrinsic_into_phi(i32 %n) {
>> +; CHECK-LABEL: @intrinsic_into_phi(
>> +; CHECK: @llvm.sadd.with.overflow.i32
>> +; CHECK-NOT: @llvm.sadd.with.overflow.i32
>> +entry:
>> +  br label %cont
>> +
>> +for.cond:                                         ; preds = %while.end
>> +  %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %.lcssa, i32 1)
>> +  %1 = extractvalue { i32, i1 } %0, 1
>> +  br i1 %1, label %trap, label %cont
>> +
>> +trap:                                             ; preds = %for.cond, %while.body
>> +  tail call void @llvm.trap()
>> +  unreachable
>> +
>> +cont:                                             ; preds = %entry, %for.cond
>> +  %2 = phi { i32, i1 } [ zeroinitializer, %entry ], [ %0, %for.cond ]
>> +  %3 = extractvalue { i32, i1 } %2, 0
>> +  %call9 = tail call i32 @bar(i32 %3)
>> +  %tobool10 = icmp eq i32 %call9, 0
>> +  br i1 %tobool10, label %while.end, label %while.body.preheader
>> +
>> +while.body.preheader:                             ; preds = %cont
>> +  br label %while.body
>> +
>> +while.cond:                                       ; preds = %while.body
>> +  %4 = extractvalue { i32, i1 } %6, 0
>> +  %call = tail call i32 @bar(i32 %4)
>> +  %tobool = icmp eq i32 %call, 0
>> +  br i1 %tobool, label %while.end, label %while.body
>> +
>> +while.body:                                       ; preds = %while.body.preheader, %while.cond
>> +  %5 = phi i32 [ %4, %while.cond ], [ %3, %while.body.preheader ]
>> +  %6 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %5, i32 1)
>> +  %7 = extractvalue { i32, i1 } %6, 1
>> +  br i1 %7, label %trap, label %while.cond
>> +
>> +while.end:                                        ; preds = %while.cond, %cont
>> +  %.lcssa = phi i32 [ %3, %cont ], [ %4, %while.cond ]
>> +  %cmp = icmp slt i32 %.lcssa, %n
>> +  br i1 %cmp, label %for.cond, label %cleanup2
>> +
>> +cleanup2:                                         ; preds = %while.end
>> +  ret void
>> +}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
> --
> Davide
>
> "There are no solved problems; there are only problems that are more
> or less solved" -- Henri Poincare


More information about the llvm-commits mailing list