[llvm] r296041 - LoopUnswitch - Simplify based on known not to a be constant.

Yung, Douglas via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 23 17:17:24 PST 2017


Hi Xin,

I don't know if you are aware, but the test you added with your commit is failing on the PS4 Windows bot. Can you take a look?

http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/5971

Douglas Yung

> -----Original Message-----
> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On Behalf Of
> Xin Tong via llvm-commits
> Sent: Thursday, February 23, 2017 15:42
> To: llvm-commits at lists.llvm.org
> Subject: [llvm] r296041 - LoopUnswitch - Simplify based on known not to a be
> constant.
> 
> Author: trentxintong
> Date: Thu Feb 23 17:42:19 2017
> New Revision: 296041
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=296041&view=rev
> Log:
> LoopUnswitch - Simplify based on known not to a be constant.
> 
> Summary: In case we do not know what the condition is in an unswitched loop,
> but we know its definitely NOT a known constant. We can perform simplifcations
> based on this information.
> 
> Reviewers: sanjoy, hfinkel, chenli, efriedma
> 
> Reviewed By: efriedma
> 
> Subscribers: david2050, llvm-commits, mzolotukhin
> 
> Differential Revision: https://reviews.llvm.org/D28968
> 
> Added:
>     llvm/trunk/test/Transforms/LoopUnswitch/simplify-with-nonvalness.ll
> Modified:
>     llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> 
> Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=296041&r1=296040
> &r2=296041&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Thu Feb 23
> +++ 17:42:19 2017
> @@ -47,6 +47,7 @@
>  #include "llvm/IR/Dominators.h"
>  #include "llvm/IR/Function.h"
>  #include "llvm/IR/Instructions.h"
> +#include "llvm/IR/InstrTypes.h"
>  #include "llvm/IR/Module.h"
>  #include "llvm/IR/MDBuilder.h"
>  #include "llvm/Support/CommandLine.h"
> @@ -235,6 +236,11 @@ namespace {
>                                          TerminatorInst *TI);
> 
>      void SimplifyCode(std::vector<Instruction*> &Worklist, Loop *L);
> +
> +    /// Given that the Invariant is not equal to Val. Simplify instructions
> +    /// in the loop.
> +    Value *SimplifyInstructionWithNotEqual(Instruction *Inst, Value
> *Invariant,
> +                                           Constant *Val);
>    };
>  }
> 
> @@ -1218,10 +1224,21 @@ void LoopUnswitch::RewriteLoopBodyWithCo
>      if (!UI || !L->contains(UI))
>        continue;
> 
> -    Worklist.push_back(UI);
> +    // At this point, we know LIC is definitely not Val. Try to use some
> simple
> +    // logic to simplify the user w.r.t. to the context.
> +    if (Value *Replacement = SimplifyInstructionWithNotEqual(UI, LIC, Val)) {
> +      if (LI->replacementPreservesLCSSAForm(UI, Replacement)) {
> +        // This in-loop instruction has been simplified w.r.t. its context,
> +        // i.e. LIC != Val, make sure we propagate its replacement value to
> +        // all its users.
> +        ReplaceUsesOfWith(UI, Replacement, Worklist, L, LPM);
> +        continue;
> +      }
> +    }
> 
> -    // TODO: We could do other simplifications, for example, turning
> -    // 'icmp eq LIC, Val' -> false.
> +    // Unable to simplify with non-valueness, push it into the worklist so
> that
> +    // SimplifyCode can attempt to simplify it.
> +    Worklist.push_back(UI);
> 
>      // If we know that LIC is not Val, use this info to simplify code.
>      SwitchInst *SI = dyn_cast<SwitchInst>(UI); @@ -1362,3 +1379,27 @@ void
> LoopUnswitch::SimplifyCode(std::vec
>      }
>    }
>  }
> +
> +/// Simple simplifications we can do given the information that Cond is
> +/// definitely not equal to Val.
> +Value *LoopUnswitch::SimplifyInstructionWithNotEqual(Instruction *Inst,
> +                                                     Value *Invariant,
> +                                                     Constant *Val) {
> +  // icmp eq cond, val -> false
> +  ICmpInst *CI = dyn_cast<ICmpInst>(Inst);
> +  if (CI && CI->isEquality()) {
> +    Value *Op0 = CI->getOperand(0);
> +    Value *Op1 = CI->getOperand(1);
> +    if ((Op0 == Invariant && Op1 == Val) || (Op0 == Val && Op1 == Invariant))
> {
> +      LLVMContext &Ctx = Inst->getContext();
> +      if (CI->getPredicate() == CmpInst::ICMP_EQ)
> +        return ConstantInt::getFalse(Ctx);
> +      else
> +        return ConstantInt::getTrue(Ctx);
> +     }
> +  }
> +
> +  // FIXME: there may be other opportunities, e.g. comparison with
> +floating
> +  // point, or Invariant - Val != 0, etc.
> +  return nullptr;
> +}
> 
> Added: llvm/trunk/test/Transforms/LoopUnswitch/simplify-with-nonvalness.ll
> URL: http://llvm.org/viewvc/llvm-
> project/llvm/trunk/test/Transforms/LoopUnswitch/simplify-with-
> nonvalness.ll?rev=296041&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/LoopUnswitch/simplify-with-nonvalness.ll
> (added)
> +++ llvm/trunk/test/Transforms/LoopUnswitch/simplify-with-nonvalness.ll
> +++ Thu Feb 23 17:42:19 2017
> @@ -0,0 +1,58 @@
> +; RUN: opt < %s -loop-unswitch -verify-loop-info -S < %s 2>&1 |
> +FileCheck %s
> +
> +; There are 1 case and 1 default case in the switch. after we unswitch,
> +we know the ; %a is definitely not 0 in one of the unswitched loop,
> +make sure we take advantage ; of that and simplify the branches in the loop.
> +;
> +; CHECK: define void @simplify_with_nonvalness(
> +
> +; This is the loop in which we know %a is definitely 0.
> +; CHECK: sw.bb.us:
> +; CHECK: br i1 true, label %if.then.us, label %if.end.us
> +
> +; This is the loop in which we do not know what %a is but we know %a is
> definitely NOT 0.
> +; Make sure we use that information to simplify.
> +; The icmp eq i32 %a, 0 in one of the unswitched loop is simplified to false.
> +; CHECK: sw.bb.split:
> +; CHECK: br i1 false, label %if.then, label %if.end
> +
> +define void @simplify_with_nonvalness(i32 %a) #0 {
> +entry:
> +  br label %for.cond
> +
> +for.cond:
> +  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
> +  %cmp = icmp slt i32 %i.0, 1024
> +  br i1 %cmp, label %for.body, label %for.end
> +
> +for.body:
> +  switch i32 %a, label %sw.default [
> +    i32 0, label %sw.bb
> +  ]
> +
> +sw.bb:
> +  %cmp1 = icmp eq i32 %a, 0
> +  br i1 %cmp1, label %if.then, label %if.end
> +
> +if.then:
> +  call void (...) @bar()
> +  br label %if.end
> +
> +if.end:
> +  br label %sw.epilog
> +
> +sw.default:
> +  br label %sw.epilog
> +
> +sw.epilog:
> +  br label %for.inc
> +
> +for.inc:
> +  %inc = add nsw i32 %i.0, 1
> +  br label %for.cond
> +
> +for.end:
> +  ret void
> +}
> +
> +declare void @bar(...)
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list