[llvm-commits] [llvm] r54786 - in /llvm/trunk: lib/Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/LoopStrengthReduce/2008-08-14-ShadowIV.ll

Dale Johannesen dalej at apple.com
Thu Aug 14 19:54:39 PDT 2008


Yeah, I looked at this for a while, but eventually concluded all the  
cases
where the behavior changes are undefined behavior in the standards.
I might have missed something, and there's an argument for not changing
the behavior anyway.

In your second example, 9907199999999999 is out of range of  
representable
unsigneds, so this patch shouldn't cause a problem.  I think it's "safe"
provided the FP type has enough mantissa bits to represent all possible
values of the int type.  Thus for 32-bit ints I think this is OK for  
double
and long double, but could change the behavior for some cases involving
float overflow.  Maybe put the insufficient-bits case under -ffast-math?

This does come up in SPEC IIRC.

On Aug 14, 2008, at 7:07 PM, Daniel Dunbar wrote:

> I'm seeing a lot of test-suite failures which I isolated to this  
> commit.
> In particular, in SingleSource/UnitTests/Vector, sse.expandfft,  
> see.stepfft,
> sumarray, and sumarray-dbl are failing.
>
>
>
> +      /* If shadow use is a int->float cast then insert a second IV
> +         to elminate this cast.
> +
> +           for (unsigned i = 0; i < n; ++i)
> +             foo((double)i);
> +
> +         is trnasformed into
> +
> +           double d = 0.0;
> +           for (unsigned i = 0; i < n; ++i, ++d)
> +             foo(d);
> +      */
>
> If this is really the transformation how can this be legal?
>  16777216.0f + 1.0f == 16777216.0f
> and
>  9007199999999999.0 + 1.0 == 9007199999999999.0
> on my machine, for example.
>
> - Daniel
>
> ----- Original Message ----
> From: Devang Patel <dpatel at apple.com>
> To: llvm-commits at cs.uiuc.edu
> Sent: Thursday, August 14, 2008 1:58:31 PM
> Subject: [llvm-commits] [llvm] r54786 - in /llvm/trunk: lib/ 
> Transforms/Scalar/LoopStrengthReduce.cpp test/Transforms/ 
> LoopStrengthReduce/2008-08-14-ShadowIV.ll
>
> Author: dpatel
> Date: Thu Aug 14 15:58:31 2008
> New Revision: 54786
>
> URL: http://llvm.org/viewvc/llvm-project?rev=54786&view=rev
> Log:
> If IV is used in a int-to-float cast inside the loop then try to  
> eliminate the cast opeation.
>
> Added:
>    llvm/trunk/test/Transforms/LoopStrengthReduce/2008-08-14- 
> ShadowIV.ll
> Modified:
>    llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp?rev=54786&r1=54785&r2=54786&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp Thu Aug  
> 14 15:58:31 2008
> @@ -45,6 +45,7 @@
> STATISTIC(NumInserted,    "Number of PHIs inserted");
> STATISTIC(NumVariable,    "Number of PHIs with variable strides");
> STATISTIC(NumEliminated , "Number of strides eliminated");
> +STATISTIC(NumShadow , "Number of Shdow IVs optimized");
>
> namespace {
>
> @@ -177,6 +178,10 @@
>                                   IVStrideUse* &CondUse,
>                                   const SCEVHandle* &CondStride);
>     void OptimizeIndvars(Loop *L);
> +
> +    /// OptimizeShadowIV - If IV is used in a int-to-float cast
> +    /// inside the loop then try to eliminate the cast opeation.
> +    void OptimizeShadowIV(Loop *L);
>     bool FindIVUserForCond(ICmpInst *Cond, IVStrideUse *&CondUse,
>                        const SCEVHandle *&CondStride);
>     bool RequiresTypeConversion(const Type *Ty, const Type *NewTy);
> @@ -1689,12 +1694,108 @@
>   return Cond;
> }
>
> +/// OptimizeShadowIV - If IV is used in a int-to-float cast
> +/// inside the loop then try to eliminate the cast opeation.
> +void LoopStrengthReduce::OptimizeShadowIV(Loop *L) {
> +
> +  for (unsigned Stride = 0, e = StrideOrder.size(); Stride != e;
> +       ++Stride) {
> +    std::map<SCEVHandle, IVUsersOfOneStride>::iterator SI =
> +      IVUsesByStride.find(StrideOrder[Stride]);
> +    assert(SI != IVUsesByStride.end() && "Stride doesn't exist!");
> +
> +    for (std::vector<IVStrideUse>::iterator UI = SI- 
> >second.Users.begin(),
> +           E = SI->second.Users.end(); UI != E; /* empty */) {
> +      std::vector<IVStrideUse>::iterator CandidateUI = UI;
> +      UI++;
> +      Instruction *ShadowUse = CandidateUI->User;
> +      const Type *DestTy = NULL;
> +
> +      /* If shadow use is a int->float cast then insert a second IV
> +         to elminate this cast.
> +
> +           for (unsigned i = 0; i < n; ++i)
> +             foo((double)i);
> +
> +         is trnasformed into
> +
> +           double d = 0.0;
> +           for (unsigned i = 0; i < n; ++i, ++d)
> +             foo(d);
> +      */
> +      UIToFPInst *UCast = dyn_cast<UIToFPInst>(CandidateUI->User);
> +      if (UCast)
> +        DestTy = UCast->getDestTy();
> +      else {
> +        SIToFPInst *SCast = dyn_cast<SIToFPInst>(CandidateUI->User);
> +        if (!SCast) continue;
> +        DestTy = SCast->getDestTy();
> +      }
> +
> +      PHINode *PH = dyn_cast<PHINode>(ShadowUse->getOperand(0));
> +      if (!PH) continue;
> +      if (PH->getNumIncomingValues() != 2) continue;
> +
> +      unsigned Entry, Latch;
> +      if (PH->getIncomingBlock(0) == L->getLoopPreheader()) {
> +        Entry = 0;
> +        Latch = 1;
> +      } else {
> +        Entry = 1;
> +        Latch = 0;
> +      }
> +
> +      ConstantInt *Init = dyn_cast<ConstantInt>(PH- 
> >getIncomingValue(Entry));
> +      if (!Init) continue;
> +      ConstantFP *NewInit = ConstantFP::get(DestTy, Init- 
> >getZExtValue());
> +
> +      BinaryOperator *Incr =
> +        dyn_cast<BinaryOperator>(PH->getIncomingValue(Latch));
> +      if (!Incr) continue;
> +      if (Incr->getOpcode() != Instruction::Add
> +          && Incr->getOpcode() != Instruction::Sub)
> +        continue;
> +
> +      /* Initialize new IV, double d = 0.0 in above example. */
> +      ConstantInt *C = NULL;
> +      if (Incr->getOperand(0) == PH)
> +        C = dyn_cast<ConstantInt>(Incr->getOperand(1));
> +      else if (Incr->getOperand(1) == PH)
> +        C = dyn_cast<ConstantInt>(Incr->getOperand(0));
> +      else
> +        continue;
> +
> +      if (!C) continue;
> +
> +      /* create new icnrement. '++d' in above example. */
> +      ConstantFP *CFP = ConstantFP::get(DestTy, C->getZExtValue());
> +      BinaryOperator *NewIncr =
> +        BinaryOperator::Create(Incr->getOpcode(),
> +                               NewInit, CFP, "IV.S.next.", Incr);
> +
> +      /* Add new PHINode. */
> +      PHINode *NewPH = PHINode::Create(DestTy, "IV.S.", PH);
> +      NewPH->addIncoming(NewInit, PH->getIncomingBlock(Entry));
> +      NewPH->addIncoming(NewIncr, PH->getIncomingBlock(Latch));
> +
> +      /* Remove cast operation */
> +      ShadowUse->replaceAllUsesWith(NewPH);
> +      ShadowUse->eraseFromParent();
> +      SI->second.Users.erase(CandidateUI);
> +      NumShadow++;
> +      break;
> +    }
> +  }
> +}
> +
> // OptimizeIndvars - Now that IVUsesByStride is set up with all of  
> the indvar
> // uses in the loop, look to see if we can eliminate some, in favor  
> of using
> // common indvars for the different uses.
> void LoopStrengthReduce::OptimizeIndvars(Loop *L) {
>   // TODO: implement optzns here.
>
> +  OptimizeShadowIV(L);
> +
>   // Finally, get the terminating condition for the loop if  
> possible.  If we
>   // can, we want to change it to use a post-incremented version of  
> its
>   // induction variable, to allow coalescing the live ranges for the  
> IV into
>
> Added: llvm/trunk/test/Transforms/LoopStrengthReduce/2008-08-14- 
> ShadowIV.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopStrengthReduce/2008-08-14-ShadowIV.ll?rev=54786&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/test/Transforms/LoopStrengthReduce/2008-08-14- 
> ShadowIV.ll (added)
> +++ llvm/trunk/test/Transforms/LoopStrengthReduce/2008-08-14- 
> ShadowIV.ll Thu Aug 14 15:58:31 2008
> @@ -0,0 +1,27 @@
> +; RUN: llvm-as < %s | opt -loop-reduce | llvm-dis | grep "phi double"
> +
> +define void @foobar(i32 %n) nounwind {
> +entry:
> +    icmp eq i32 %n, 0        ; <i1>:0 [#uses=2]
> +    br i1 %0, label %return, label %bb.nph
> +
> +bb.nph:        ; preds = %entry
> +    %umax = select i1 %0, i32 1, i32 %n        ; <i32> [#uses=1]
> +    br label %bb
> +
> +bb:        ; preds = %bb, %bb.nph
> +    %i.03 = phi i32 [ 0, %bb.nph ], [ %indvar.next, %bb ]        ;  
> <i32> [#uses=3]
> +    tail call void @bar( i32 %i.03 ) nounwind
> +    uitofp i32 %i.03 to double        ; <double>:1 [#uses=1]
> +    tail call void @foo( double %1 ) nounwind
> +    %indvar.next = add i32 %i.03, 1        ; <i32> [#uses=2]
> +    %exitcond = icmp eq i32 %indvar.next, %umax        ; <i1>  
> [#uses=1]
> +    br i1 %exitcond, label %return, label %bb
> +
> +oreturn:        ; preds = %bb, %entry
> +    ret void
> +}
> +
> +declare void @bar(i32)
> +
> +declare void @foo(double)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list