[llvm] r331935 - [InstCombine] Widen guards with conditions between

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Wed May 9 17:09:37 PDT 2018


Fixed.  And thanks for the email btw.

Committed revision 331944.


On 05/09/2018 05:00 PM, Philip Reames via llvm-commits wrote:
>
> patch in progress, eta < 5 minutes
>
>
> On 05/09/2018 04:57 PM, Evgenii Stepanov wrote:
>> Breaks WERROR,
>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux/builds/11432/steps/bootstrap%20clang/logs/stdio
>>
>> On Wed, May 9, 2018 at 3:56 PM, Philip Reames via llvm-commits 
>> <llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>> wrote:
>>
>>     Author: reames
>>     Date: Wed May  9 15:56:32 2018
>>     New Revision: 331935
>>
>>     URL: http://llvm.org/viewvc/llvm-project?rev=331935&view=rev
>>     <http://llvm.org/viewvc/llvm-project?rev=331935&view=rev>
>>     Log:
>>     [InstCombine] Widen guards with conditions between
>>
>>     The previous handling for guard widening in InstCombine was
>>     extremely restrictive. In particular, it didn't handle the common
>>     case where we had two guards separated by a single icmp. Handle
>>     this by scanning through a small fixed window of instructions to
>>     find the next guard if needed.
>>
>>     Differential Revision: https://reviews.llvm.org/D46203
>>     <https://reviews.llvm.org/D46203>
>>
>>
>>     Modified:
>>         llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
>>         llvm/trunk/test/Transforms/InstCombine/call-guard.ll
>>
>>     Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
>>     URL:
>>     http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=331935&r1=331934&r2=331935&view=diff
>>     <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=331935&r1=331934&r2=331935&view=diff>
>>     ==============================================================================
>>     --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
>>     (original)
>>     +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp
>>     Wed May  9 15:56:32 2018
>>     @@ -79,6 +79,13 @@ static cl::opt<unsigned> UnfoldElementAt
>>          cl::desc("Maximum number of elements in atomic memcpy the
>>     optimizer is "
>>                   "allowed to unfold"));
>>
>>     +static cl::opt<unsigned> GuardWideningWindow(
>>     +    "instcombine-guard-widening-window",
>>     +    cl::init(3),
>>     +    cl::desc("How wide an instruction window to bypass looking for "
>>     +             "another guard"));
>>     +
>>     +
>>      /// Return the specified type promoted as it would be to pass
>>     though a va_arg
>>      /// area.
>>      static Type *getPromotedType(Type *Ty) {
>>     @@ -3624,8 +3631,16 @@ Instruction *InstCombiner::visitCallInst
>>        }
>>
>>        case Intrinsic::experimental_guard: {
>>     -    // Is this guard followed by another guard?
>>     +    // Is this guard followed by another guard?  We scan forward
>>     over a small
>>     +    // fixed window of instructions to handle common cases with
>>     conditions
>>     +    // computed between guards.
>>          Instruction *NextInst = II->getNextNode();
>>     +    for (int i = 0; i < GuardWideningWindow; i++) {
>>     +      // Note: Using context-free form to avoid compile time blow up
>>     +      if (!isSafeToSpeculativelyExecute(NextInst))
>>     +        break;
>>     +      NextInst = NextInst->getNextNode();
>>     +    }
>>          Value *NextCond = nullptr;
>>          if (match(NextInst,
>>                  
>>      m_Intrinsic<Intrinsic::experimental_guard>(m_Value(NextCond)))) {
>>     @@ -3636,6 +3651,12 @@ Instruction *InstCombiner::visitCallInst
>>              return eraseInstFromFunction(*NextInst);
>>
>>            // Otherwise canonicalize guard(a); guard(b) -> guard(a & b).
>>     +      Instruction* MoveI = II->getNextNode();
>>     +      while (MoveI != NextInst) {
>>     +        auto *Temp = MoveI;
>>     +        MoveI = MoveI->getNextNode();
>>     +        Temp->moveBefore(II);
>>     +      }
>>            II->setArgOperand(0, Builder.CreateAnd(CurrCond, NextCond));
>>            return eraseInstFromFunction(*NextInst);
>>          }
>>
>>     Modified: llvm/trunk/test/Transforms/InstCombine/call-guard.ll
>>     URL:
>>     http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/call-guard.ll?rev=331935&r1=331934&r2=331935&view=diff
>>     <http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/call-guard.ll?rev=331935&r1=331934&r2=331935&view=diff>
>>     ==============================================================================
>>     --- llvm/trunk/test/Transforms/InstCombine/call-guard.ll (original)
>>     +++ llvm/trunk/test/Transforms/InstCombine/call-guard.ll Wed May 
>>     9 15:56:32 2018
>>     @@ -30,3 +30,81 @@ define void @test_guard_adjacent_diff_co
>>        call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[
>>     "deopt"() ]
>>        ret void
>>      }
>>     +
>>     +; This version tests for the common form where the conditions are
>>     +; between the guards
>>     +define void @test_guard_adjacent_diff_cond2(i32 %V1, i32 %V2) {
>>     +; CHECK-LABEL: @test_guard_adjacent_diff_cond2(
>>     +; CHECK-NEXT:    %1 = and i32 %V1, %V2
>>     +; CHECK-NEXT:    %2 = icmp slt i32 %1, 0
>>     +; CHECK-NEXT:    %and = and i32 %V1, 255
>>     +; CHECK-NEXT:    %C = icmp ult i32 %and, 129
>>     +; CHECK-NEXT:    %3 = and i1 %2, %C
>>     +; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1
>>     %3, i32 123) [ "deopt"() ]
>>     +; CHECK-NEXT:    ret void
>>     +  %A = icmp slt i32 %V1, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[
>>     "deopt"() ]
>>     +  %B = icmp slt i32 %V2, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[
>>     "deopt"() ]
>>     +  %and = and i32 %V1, 255
>>     +  %C = icmp sle i32 %and, 128
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[
>>     "deopt"() ]
>>     +  ret void
>>     +}
>>     +
>>     +; Might not be legal to hoist the load above the first guard
>>     since the
>>     +; guard might control dereferenceability
>>     +define void @negative_load(i32 %V1, i32* %P) {
>>     +; CHECK-LABEL: @negative_load
>>     +; CHECK:    @llvm.experimental.guard
>>     +; CHECK:    @llvm.experimental.guard
>>     +  %A = icmp slt i32 %V1, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[
>>     "deopt"() ]
>>     +  %V2 = load i32, i32* %P
>>     +  %B = icmp slt i32 %V2, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[
>>     "deopt"() ]
>>     +  ret void
>>     +}
>>     +
>>     +define void @deref_load(i32 %V1, i32* dereferenceable(4) %P) {
>>     +; CHECK-LABEL: @deref_load
>>     +; CHECK-NEXT:  %V2 = load i32, i32* %P, align 4
>>     +; CHECK-NEXT:  %1 = and i32 %V2, %V1
>>     +; CHECK-NEXT:  %2 = icmp slt i32 %1, 0
>>     +; CHECK-NEXT:  call void (i1, ...) @llvm.experimental.guard(i1
>>     %2, i32 123) [ "deopt"() ]
>>     +  %A = icmp slt i32 %V1, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[
>>     "deopt"() ]
>>     +  %V2 = load i32, i32* %P
>>     +  %B = icmp slt i32 %V2, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[
>>     "deopt"() ]
>>     +  ret void
>>     +}
>>     +
>>     +; The divide might fault above the guard
>>     +define void @negative_div(i32 %V1, i32 %D) {
>>     +; CHECK-LABEL: @negative_div
>>     +; CHECK:    @llvm.experimental.guard
>>     +; CHECK:    @llvm.experimental.guard
>>     +  %A = icmp slt i32 %V1, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[
>>     "deopt"() ]
>>     +  %V2 = udiv i32 %V1, %D
>>     +  %B = icmp slt i32 %V2, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[
>>     "deopt"() ]
>>     +  ret void
>>     +}
>>     +
>>     +; Highlight the limit of the window in a case which would
>>     otherwise be mergable
>>     +define void @negative_window(i32 %V1, i32 %a, i32 %b, i32 %c,
>>     i32 %d) {
>>     +; CHECK-LABEL: @negative_window
>>     +; CHECK:    @llvm.experimental.guard
>>     +; CHECK:    @llvm.experimental.guard
>>     +  %A = icmp slt i32 %V1, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[
>>     "deopt"() ]
>>     +  %V2 = add i32 %a, %b
>>     +  %V3 = add i32 %V2, %c
>>     +  %V4 = add i32 %V3, %d
>>     +  %B = icmp slt i32 %V4, 0
>>     +  call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[
>>     "deopt"() ]
>>     +  ret void
>>     +}
>>     +
>>
>>
>>     _______________________________________________
>>     llvm-commits mailing list
>>     llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>>     http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits>
>>
>>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180509/4af7dd16/attachment.html>


More information about the llvm-commits mailing list