[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / IRCE / bad_expander.ll
blob5dd9ab2752cacbd1c725a991987cefde13a4b432
1 ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce -S < %s 2>&1 | FileCheck %s
2 ; RUN: opt -verify-loop-info -irce-print-changed-loops -passes='require<branch-prob>,loop(irce)' -S < %s 2>&1 | FileCheck %s
4 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:1"
5 target triple = "x86_64-unknown-linux-gnu"
7 ; IRCE should fail here because the preheader's exiting value is a phi from the
8 ; loop, and this value cannot be expanded at loop's preheader.
10 ; CHECK-NOT:   irce: in function test_01: constrained Loop
11 ; CHECK-NOT:   irce: in function test_02: constrained Loop
12 ; CHECK-LABEL: irce: in function test_03: constrained Loop
14 define void @test_01() {
16 ; CHECK-NOT:   irce: in function test_01: constrained Loop
18 ; CHECK-LABEL: test_01
19 ; CHECK-NOT:   preloop
20 ; CHECK-NOT:   postloop
21 ; CHECK-NOT:   br i1 false
22 ; CHECK-NOT:   br i1 true
24 entry:
25   br label %loop
27 exit:                                       ; preds = %guarded, %loop
28   ret void
30 loop:                                      ; preds = %guarded, %entry
31   %iv = phi i64 [ 380, %entry ], [ %limit, %guarded ]
32   %bad_phi = phi i32 [ 3, %entry ], [ %bad_phi.next, %guarded ]
33   %bad_phi.next = add nuw nsw i32 %bad_phi, 1
34   %iv.next = add nuw nsw i64 %iv, 1
35   %rc = icmp slt i64 %iv.next, 5
36   br i1 %rc, label %guarded, label %exit
38 guarded:
39   %limit = add nsw i64 %iv, -1
40   %tmp5 = add nuw nsw i32 %bad_phi, 8
41   %tmp6 = zext i32 %tmp5 to i64
42   %tmp7 = icmp eq i64 %limit, %tmp6
43   br i1 %tmp7, label %exit, label %loop
46 ; This test should fail because we are unable to prove that the division is
47 ; safe to expand it to preheader: if we exit by maybe_exit condition, it is
48 ; unsafe to execute it there.
50 define void @test_02(i64* %p1, i64* %p2, i1 %maybe_exit) {
52 ; CHECK-LABEL: test_02
53 ; CHECK-NOT:   preloop
54 ; CHECK-NOT:   postloop
55 ; CHECK-NOT:   br i1 false
56 ; CHECK-NOT:   br i1 true
59 entry:
60   %num = load i64, i64* %p1, align 4, !range !0
61   %denom = load i64, i64* %p2, align 4, !range !0
62   br label %loop
64 exit:                                       ; preds = %guarded, %loop
65   ret void
67 loop:                                      ; preds = %guarded, %entry
68   %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ]
69   %iv.next = add nuw nsw i64 %iv, 1
70   br i1 %maybe_exit, label %range_check, label %exit
72 range_check:
73   %div_result = udiv i64 %num, %denom
74   %rc = icmp slt i64 %iv.next, %div_result
75   br i1 %rc, label %guarded, label %exit
77 guarded:
78   %gep = getelementptr i64, i64* %p1, i64 %iv.next
79   %loaded = load i64, i64* %gep, align 4
80   %tmp7 = icmp slt i64 %iv.next, 1000
81   br i1 %tmp7, label %loop, label %exit
84 define void @test_03(i64* %p1, i64* %p2, i1 %maybe_exit) {
86 ; Show that IRCE would hit test_02 if the division was safe (denom not zero).
88 ; CHECK-LABEL: test_03
89 ; CHECK:       entry:
90 ; CHECK-NEXT:    %num = load i64, i64* %p1, align 4
91 ; CHECK-NEXT:    [[DIV:%[^ ]+]] = udiv i64 %num, 13
92 ; CHECK-NEXT:    [[DIV_MINUS_1:%[^ ]+]] = add nsw i64 [[DIV]], -1
93 ; CHECK-NEXT:    [[COMP1:%[^ ]+]] = icmp sgt i64 [[DIV_MINUS_1]], 0
94 ; CHECK-NEXT:    %exit.mainloop.at = select i1 [[COMP1]], i64 [[DIV_MINUS_1]], i64 0
95 ; CHECK-NEXT:    [[COMP2:%[^ ]+]] = icmp slt i64 0, %exit.mainloop.at
96 ; CHECK-NEXT:    br i1 [[COMP2]], label %loop.preheader, label %main.pseudo.exit
97 ; CHECK-NOT:     preloop
98 ; CHECK:       loop:
99 ; CHECK-NEXT:    %iv = phi i64 [ %iv.next, %guarded ], [ 0, %loop.preheader ]
100 ; CHECK-NEXT:    %iv.next = add nuw nsw i64 %iv, 1
101 ; CHECK-NEXT:    %rc = icmp slt i64 %iv.next, %div_result
102 ; CHECK-NEXT:    %or.cond = and i1 %maybe_exit, true
103 ; CHECK-NEXT:    br i1 %or.cond, label %guarded, label %exit.loopexit1
104 ; CHECK:       guarded:
105 ; CHECK-NEXT:    %gep = getelementptr i64, i64* %p1, i64 %iv.next
106 ; CHECK-NEXT:    %loaded = load i64, i64* %gep, align 4
107 ; CHECK-NEXT:    %tmp7 = icmp slt i64 %iv.next, 1000
108 ; CHECK-NEXT:    [[EXIT_MAIN_LOOP:%[^ ]+]] = icmp slt i64 %iv.next, %exit.mainloop.at
109 ; CHECK-NEXT:    br i1 [[EXIT_MAIN_LOOP]], label %loop, label %main.exit.selector
110 ; CHECK:       postloop
112 entry:
113   %num = load i64, i64* %p1, align 4, !range !0
114   br label %loop
116 exit:                                       ; preds = %guarded, %loop
117   ret void
119 loop:                                      ; preds = %guarded, %entry
120   %iv = phi i64 [ 0, %entry ], [ %iv.next, %guarded ]
121   %iv.next = add nuw nsw i64 %iv, 1
122   br i1 %maybe_exit, label %range_check, label %exit
124 range_check:
125   %div_result = udiv i64 %num, 13
126   %rc = icmp slt i64 %iv.next, %div_result
127   br i1 %rc, label %guarded, label %exit
129 guarded:
130   %gep = getelementptr i64, i64* %p1, i64 %iv.next
131   %loaded = load i64, i64* %gep, align 4
132   %tmp7 = icmp slt i64 %iv.next, 1000
133   br i1 %tmp7, label %loop, label %exit
136 !0 = !{i64 0, i64 100}