[llvm] be0bf04 - [ConstraintElimination] Add some tests with conds in loop header.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 3 08:41:13 PST 2021


Author: Florian Hahn
Date: 2021-02-03T16:40:43Z
New Revision: be0bf04b19ffa380ef2f15fefa402ac1b6d29f03

URL: https://github.com/llvm/llvm-project/commit/be0bf04b19ffa380ef2f15fefa402ac1b6d29f03
DIFF: https://github.com/llvm/llvm-project/commit/be0bf04b19ffa380ef2f15fefa402ac1b6d29f03.diff

LOG: [ConstraintElimination] Add some tests with conds in loop header.

This patch adds a set of tests in which we can add the information from
the pre-header to a loop header, but currently do not do so.

Added: 
    

Modified: 
    llvm/test/Transforms/ConstraintElimination/dom.ll
    llvm/test/Transforms/ConstraintElimination/loops.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/ConstraintElimination/dom.ll b/llvm/test/Transforms/ConstraintElimination/dom.ll
index 2f386fa2b835..424e98742289 100644
--- a/llvm/test/Transforms/ConstraintElimination/dom.ll
+++ b/llvm/test/Transforms/ConstraintElimination/dom.ll
@@ -135,3 +135,434 @@ bb2:
   call void @use(i1 %c.3)
   ret i32 20
 }
+
+
+define void @test_cond_from_preheader(i32 %x, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
+; CHECK:       pre:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP:%.*]], label [[BB2]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %bb2
+
+pre:
+  %c.1 = icmp ule i32 %x, 10
+  br i1 %c.1, label %loop, label %bb2
+
+loop:
+  %t.1 = icmp ule i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %f.1)
+
+  %c.2 = icmp ule i32 %x, 9
+  call void @use(i1 %c.2)
+  %c.3 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.3)
+
+  br i1 true, label %exit, label %loop
+
+exit:
+  %c.4 = icmp ule i32 %x, 10
+  call void @use(i1 %c.4)
+  ret void
+
+bb2:
+  %c.5 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.5)
+  ret void
+}
+
+define void @test_cond_from_preheader_successors_flipped(i32 %x, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader_successors_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[BB2:%.*]]
+; CHECK:       pre:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    br i1 [[C_1]], label [[BB2]], label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    br i1 true, label [[EXIT:%.*]], label [[LOOP]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    ret void
+; CHECK:       bb2:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %bb2
+
+pre:
+  %c.1 = icmp ule i32 %x, 10
+  br i1 %c.1, label %bb2, label %loop
+
+loop:
+  %f.1 = icmp ule i32 %x, 10
+  call void @use(i1 %f.1)
+  %t.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %t.1)
+
+  %c.2 = icmp ule i32 %x, 11
+  call void @use(i1 %c.2)
+  %c.3 = icmp ugt i32 %x, 11
+  call void @use(i1 %c.3)
+
+  br i1 true, label %exit, label %loop
+
+exit:
+  %f.2 = icmp ule i32 %x, 10
+  call void @use(i1 %f.2)
+  ret void
+
+bb2:
+  %c.5 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.5)
+  ret void
+}
+
+define void @test_cond_from_preheader_and(i32 %x, i32 %y, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader_and(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+; CHECK:       pre:
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[AND]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %exit
+
+exit:
+  %c.5 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.5)
+  ret void
+
+pre:
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %and = and i1 %x.1, %y.1
+  br i1 %and, label %loop, label %exit.1
+
+loop:
+  %t.1 = icmp ule i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %f.1)
+  %c.1 = icmp ule i32 %x, 9
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.2)
+
+
+  %t.2 = icmp ugt i32 %y, 99
+  call void @use(i1 %t.2)
+  %f.2 = icmp ule i32 %y, 99
+  call void @use(i1 %f.2)
+
+  %c.3 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.4)
+
+  br i1 true, label %exit, label %loop
+
+exit.1:
+  %c.6 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.6)
+  ret void
+}
+
+
+define void @test_cond_from_preheader_and_successors_flipped(i32 %x, i32 %y, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader_and_successors_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_9]])
+; CHECK-NEXT:    ret void
+; CHECK:       pre:
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_7]])
+; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_8]])
+; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %exit
+
+exit:
+  %c.9 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.9)
+  ret void
+
+pre:
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %and = and i1 %x.1, %y.1
+  br i1 %and, label %exit.1, label %loop
+
+loop:
+  %c.1 = icmp ule i32 %x, 10
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.2)
+  %c.3 = icmp ule i32 %x, 9
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.4)
+
+
+  %c.5 = icmp ugt i32 %y, 99
+  call void @use(i1 %c.5)
+  %c.6 = icmp ule i32 %y, 99
+  call void @use(i1 %c.6)
+
+  %c.7 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.7)
+  %c.8 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.8)
+
+  br i1 true, label %exit, label %loop
+
+exit.1:
+  %t.1 = icmp ugt i32 %y, 10
+  call void @use(i1 %t.1)
+  ret void
+}
+
+define void @test_cond_from_preheader_or(i32 %x, i32 %y, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader_or(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+; CHECK:       pre:
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[EXIT_1:%.*]], label [[LOOP:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[F_1]])
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[T_2]])
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[F_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[Y]], 98
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i32 [[Y]], 98
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %exit
+
+exit:
+  %c.5 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.5)
+  ret void
+
+pre:
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %or = or i1 %x.1, %y.1
+  br i1 %or, label %exit.1, label %loop
+
+loop:
+  %t.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ule i32 %x, 10
+  call void @use(i1 %f.1)
+  %c.1 = icmp ugt i32 %x, 11
+  call void @use(i1 %c.1)
+  %c.2 = icmp ule i32 %x, 11
+  call void @use(i1 %c.2)
+
+
+  %t.2 = icmp ule i32 %y, 99
+  call void @use(i1 %t.2)
+  %f.2 = icmp ugt i32 %y, 99
+  call void @use(i1 %f.2)
+
+  %c.3 = icmp ule i32 %y, 98
+  call void @use(i1 %c.3)
+  %c.4 = icmp ule i32 %y, 98
+  call void @use(i1 %c.4)
+
+  br i1 true, label %exit, label %loop
+
+exit.1:
+  %c.6 = icmp ule i32 %y, 100
+  call void @use(i1 %c.6)
+  ret void
+}
+
+define void @test_cond_from_preheader_or_successor_flipped(i32 %x, i32 %y, i1 %c) {
+; CHECK-LABEL: @test_cond_from_preheader_or_successor_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[PRE:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_9]])
+; CHECK-NEXT:    ret void
+; CHECK:       pre:
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X:%.*]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[LOOP:%.*]], label [[EXIT_1:%.*]]
+; CHECK:       loop:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_7]])
+; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_8]])
+; CHECK-NEXT:    br i1 true, label [[EXIT]], label [[LOOP]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %pre, label %exit
+
+exit:
+  %c.9 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.9)
+  ret void
+
+pre:
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %or = or i1 %x.1, %y.1
+  br i1 %or, label %loop, label %exit.1
+
+loop:
+  %c.1 = icmp ule i32 %x, 10
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.2)
+  %c.3 = icmp ule i32 %x, 9
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.4)
+
+  %c.5 = icmp ugt i32 %y, 99
+  call void @use(i1 %c.5)
+  %c.6 = icmp ule i32 %y, 99
+  call void @use(i1 %c.6)
+
+  %c.7 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.7)
+  %c.8 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.8)
+
+  br i1 true, label %exit, label %loop
+
+exit.1:
+  %t.1 = icmp ule i32 %y, 100
+  call void @use(i1 %t.1)
+  ret void
+}

diff  --git a/llvm/test/Transforms/ConstraintElimination/loops.ll b/llvm/test/Transforms/ConstraintElimination/loops.ll
index 37373e1fbcaf..a0289ab2911d 100644
--- a/llvm/test/Transforms/ConstraintElimination/loops.ll
+++ b/llvm/test/Transforms/ConstraintElimination/loops.ll
@@ -1,6 +1,8 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt -constraint-elimination -S %s | FileCheck %s
 
+declare void @use(i1)
+
 ; Make sure conditions in loops are not used to simplify themselves.
 
 define void @loop1(float* %T, float* %x, i32 %points, i32 %trigint) {
@@ -45,3 +47,426 @@ do.body:                                          ; preds = %do.body, %entry
 do.end:                                           ; preds = %do.body
   ret void
 }
+
+
+; Some tests with loops with conditions in the header.
+
+define i32 @loop_header_dom(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    br i1 [[C_1]], label [[LOOP_LATCH]], label [[EXIT]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    ret i32 20
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %c.1 = icmp ule i32 %x, 10
+  br i1 %c.1, label %loop.latch, label %exit
+
+loop.latch:
+  %t.1 = icmp ule i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %f.1)
+
+  %c.2 = icmp ule i32 %x, 9
+  call void @use(i1 %c.2)
+  %c.3 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.3)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit:
+  %c.4 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.4)
+  ret i32 20
+}
+
+define i32 @loop_header_dom_successors_flipped(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom_successors_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    br i1 [[C_1]], label [[EXIT]], label [[LOOP_LATCH]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    ret i32 20
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %c.1 = icmp ule i32 %x, 10
+  br i1 %c.1, label %exit, label %loop.latch
+
+loop.latch:
+  %f.1 = icmp ule i32 %x, 10
+  call void @use(i1 %f.1)
+  %t.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %t.1)
+
+  %c.2 = icmp ugt i32 %x, 11
+  call void @use(i1 %c.2)
+  %c.3 = icmp ule i32 %x,11
+  call void @use(i1 %c.3)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit:
+  %c.4 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.4)
+  ret i32 20
+}
+
+
+define void @loop_header_dom_or(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom_or(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y:%.*]], 99
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[EXIT]], label [[LOOP_LATCH]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ugt i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ule i32 [[X]], 11
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[Y]], 98
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ule i32 [[Y]], 98
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %or = or i1 %x.1, %y.1
+  br i1 %or, label %exit, label %loop.latch
+
+loop.latch:
+  %t.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ule i32 %x, 10
+  call void @use(i1 %f.1)
+  %c.1 = icmp ugt i32 %x, 11
+  call void @use(i1 %c.1)
+  %c.2 = icmp ule i32 %x, 11
+  call void @use(i1 %c.2)
+
+
+  %t.2 = icmp ule i32 %y, 99
+  call void @use(i1 %t.2)
+  %f.2 = icmp ugt i32 %y, 99
+  call void @use(i1 %f.2)
+
+  %c.3 = icmp ule i32 %y, 98
+  call void @use(i1 %c.3)
+  %c.4 = icmp ule i32 %y, 98
+  call void @use(i1 %c.4)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit:
+  %c.5 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.5)
+  ret void
+}
+
+define void @loop_header_dom_or_successors_flipped(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom_or_successors_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y:%.*]], 99
+; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[OR]], label [[LOOP_LATCH]], label [[EXIT]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_7]])
+; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_8]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 [[T_1]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %or = or i1 %x.1, %y.1
+  br i1 %or, label %loop.latch, label %exit
+
+loop.latch:
+  %c.1 = icmp ule i32 %x, 10
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.2)
+  %c.3 = icmp ule i32 %x, 9
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.4)
+
+
+  %c.5 = icmp ugt i32 %y, 99
+  call void @use(i1 %c.5)
+  %c.6 = icmp ule i32 %y, 99
+  call void @use(i1 %c.6)
+
+  %c.7 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.7)
+  %c.8 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.8)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit:
+  %t.1 = icmp ugt i32 %y, 10
+  call void @use(i1 %t.1)
+  ret void
+}
+
+
+define void @loop_header_dom_and(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom_and(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    ret void
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[AND]], label [[LOOP_LATCH]], label [[EXIT_1:%.*]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[F_1:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[T_2:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    [[F_2:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 false)
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+exit:
+  %c.5 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.5)
+  ret void
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %and = and i1 %x.1, %y.1
+  br i1 %and, label %loop.latch, label %exit.1
+
+loop.latch:
+  %t.1 = icmp ule i32 %x, 10
+  call void @use(i1 %t.1)
+  %f.1 = icmp ugt i32 %x, 10
+  call void @use(i1 %f.1)
+  %c.1 = icmp ule i32 %x, 9
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.2)
+
+
+  %t.2 = icmp ugt i32 %y, 99
+  call void @use(i1 %t.2)
+  %f.2 = icmp ule i32 %y, 99
+  call void @use(i1 %f.2)
+
+  %c.3 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.4)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit.1:
+  %c.6 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.6)
+  ret void
+}
+
+define void @loop_header_dom_and_successors_flipped(i32 %y, i1 %c) {
+; CHECK-LABEL: @loop_header_dom_and_successors_flipped(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[LOOP_HEADER:%.*]], label [[EXIT:%.*]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[C_9:%.*]] = icmp ugt i32 [[Y:%.*]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_9]])
+; CHECK-NEXT:    ret void
+; CHECK:       loop.header:
+; CHECK-NEXT:    [[X:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[X_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
+; CHECK-NEXT:    [[X_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    [[Y_1:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    [[AND:%.*]] = and i1 [[X_1]], [[Y_1]]
+; CHECK-NEXT:    br i1 [[AND]], label [[EXIT_1:%.*]], label [[LOOP_LATCH]]
+; CHECK:       loop.latch:
+; CHECK-NEXT:    [[C_1:%.*]] = icmp ule i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_1]])
+; CHECK-NEXT:    [[C_2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT:    call void @use(i1 [[C_2]])
+; CHECK-NEXT:    [[C_3:%.*]] = icmp ule i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_3]])
+; CHECK-NEXT:    [[C_4:%.*]] = icmp ugt i32 [[X]], 9
+; CHECK-NEXT:    call void @use(i1 [[C_4]])
+; CHECK-NEXT:    [[C_5:%.*]] = icmp ugt i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_5]])
+; CHECK-NEXT:    [[C_6:%.*]] = icmp ule i32 [[Y]], 99
+; CHECK-NEXT:    call void @use(i1 [[C_6]])
+; CHECK-NEXT:    [[C_7:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_7]])
+; CHECK-NEXT:    [[C_8:%.*]] = icmp ugt i32 [[Y]], 100
+; CHECK-NEXT:    call void @use(i1 [[C_8]])
+; CHECK-NEXT:    [[X_NEXT]] = add i32 [[X]], 1
+; CHECK-NEXT:    br label [[LOOP_HEADER]]
+; CHECK:       exit.1:
+; CHECK-NEXT:    [[T_1:%.*]] = icmp ugt i32 [[Y]], 10
+; CHECK-NEXT:    call void @use(i1 true)
+; CHECK-NEXT:    ret void
+;
+entry:
+  br i1 %c, label %loop.header, label %exit
+
+exit:
+  %c.9 = icmp ugt i32 %y, 10
+  call void @use(i1 %c.9)
+  ret void
+
+loop.header:
+  %x = phi i32 [ 0, %entry ], [ %x.next, %loop.latch ]
+  %x.1 = icmp ule i32 %x, 10
+  %y.1 = icmp ugt i32 %y, 99
+  %and = and i1 %x.1, %y.1
+  br i1 %and, label %exit.1, label %loop.latch
+
+loop.latch:
+  %c.1 = icmp ule i32 %x, 10
+  call void @use(i1 %c.1)
+  %c.2 = icmp ugt i32 %x, 10
+  call void @use(i1 %c.2)
+  %c.3 = icmp ule i32 %x, 9
+  call void @use(i1 %c.3)
+  %c.4 = icmp ugt i32 %x, 9
+  call void @use(i1 %c.4)
+
+
+  %c.5 = icmp ugt i32 %y, 99
+  call void @use(i1 %c.5)
+  %c.6 = icmp ule i32 %y, 99
+  call void @use(i1 %c.6)
+
+  %c.7 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.7)
+  %c.8 = icmp ugt i32 %y, 100
+  call void @use(i1 %c.8)
+
+  %x.next = add i32 %x, 1
+  br label %loop.header
+
+exit.1:
+  %t.1 = icmp ugt i32 %y, 10
+  call void @use(i1 %t.1)
+  ret void
+}


        


More information about the llvm-commits mailing list