Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / GuardWidening / two_forms_behavior_consistency.ll
blob1a9ff304837e335d1a72ba7a0d316d58fdb3e038
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -S -passes="guard-widening,make-guards-explicit,simplifycfg" < %s        | FileCheck %s --check-prefixes=INTRINSIC_FORM
3 ; RUN: opt -S -passes="make-guards-explicit,guard-widening,simplifycfg" < %s        | FileCheck %s --check-prefixes=BRANCH_FORM
4 ; RUN: opt -S -passes="make-guards-explicit,loop-mssa(licm),guard-widening,simplifycfg" < %s        | FileCheck %s --check-prefixes=BRANCH_FORM_LICM
6 declare i1 @cond() readonly
8 ; FIXME We want to make sure that guard widening works in the same way, no matter what form of
9 ;       guards it is dealing with.
10 ; We also want to make sure that LICM doesn't mess with widenable conditions, what might
11 ; make things more complex.
13 define void @test_01(i32 %a, i32 %b, i32 %c, i32 %d) {
14 ; INTRINSIC_FORM-LABEL: define void @test_01
15 ; INTRINSIC_FORM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
16 ; INTRINSIC_FORM-NEXT:  entry:
17 ; INTRINSIC_FORM-NEXT:    [[D_GW_FR:%.*]] = freeze i32 [[D]]
18 ; INTRINSIC_FORM-NEXT:    [[C_GW_FR:%.*]] = freeze i32 [[C]]
19 ; INTRINSIC_FORM-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B]]
20 ; INTRINSIC_FORM-NEXT:    br label [[LOOP:%.*]]
21 ; INTRINSIC_FORM:       loop:
22 ; INTRINSIC_FORM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ]
23 ; INTRINSIC_FORM-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
24 ; INTRINSIC_FORM-NEXT:    [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
25 ; INTRINSIC_FORM-NEXT:    [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
26 ; INTRINSIC_FORM-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
27 ; INTRINSIC_FORM-NEXT:    [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
28 ; INTRINSIC_FORM-NEXT:    [[WIDE_CHK1:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
29 ; INTRINSIC_FORM-NEXT:    [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
30 ; INTRINSIC_FORM-NEXT:    [[WIDE_CHK2:%.*]] = and i1 [[WIDE_CHK1]], [[C4]]
31 ; INTRINSIC_FORM-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
32 ; INTRINSIC_FORM-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK2]], [[WIDENABLE_COND]]
33 ; INTRINSIC_FORM-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
34 ; INTRINSIC_FORM:       deopt:
35 ; INTRINSIC_FORM-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
36 ; INTRINSIC_FORM-NEXT:    ret void
37 ; INTRINSIC_FORM:       guarded:
38 ; INTRINSIC_FORM-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
39 ; INTRINSIC_FORM-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
40 ; INTRINSIC_FORM:       exit:
41 ; INTRINSIC_FORM-NEXT:    ret void
43 ; BRANCH_FORM-LABEL: define void @test_01
44 ; BRANCH_FORM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
45 ; BRANCH_FORM-NEXT:  entry:
46 ; BRANCH_FORM-NEXT:    [[D_GW_FR:%.*]] = freeze i32 [[D]]
47 ; BRANCH_FORM-NEXT:    [[C_GW_FR:%.*]] = freeze i32 [[C]]
48 ; BRANCH_FORM-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B]]
49 ; BRANCH_FORM-NEXT:    br label [[LOOP:%.*]]
50 ; BRANCH_FORM:       loop:
51 ; BRANCH_FORM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ]
52 ; BRANCH_FORM-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
53 ; BRANCH_FORM-NEXT:    [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
54 ; BRANCH_FORM-NEXT:    [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
55 ; BRANCH_FORM-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
56 ; BRANCH_FORM-NEXT:    [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
57 ; BRANCH_FORM-NEXT:    [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
58 ; BRANCH_FORM-NEXT:    [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
59 ; BRANCH_FORM-NEXT:    [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
60 ; BRANCH_FORM-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
61 ; BRANCH_FORM-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
62 ; BRANCH_FORM-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
63 ; BRANCH_FORM:       deopt:
64 ; BRANCH_FORM-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
65 ; BRANCH_FORM-NEXT:    ret void
66 ; BRANCH_FORM:       guarded:
67 ; BRANCH_FORM-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
68 ; BRANCH_FORM-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[C2]], [[WIDENABLE_COND3]]
69 ; BRANCH_FORM-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
70 ; BRANCH_FORM-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[C3]], [[WIDENABLE_COND7]]
71 ; BRANCH_FORM-NEXT:    [[WIDENABLE_COND11:%.*]] = call i1 @llvm.experimental.widenable.condition()
72 ; BRANCH_FORM-NEXT:    [[EXIPLICIT_GUARD_COND12:%.*]] = and i1 [[C4]], [[WIDENABLE_COND11]]
73 ; BRANCH_FORM-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
74 ; BRANCH_FORM-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
75 ; BRANCH_FORM:       exit:
76 ; BRANCH_FORM-NEXT:    ret void
78 ; BRANCH_FORM_LICM-LABEL: define void @test_01
79 ; BRANCH_FORM_LICM-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32 [[D:%.*]]) {
80 ; BRANCH_FORM_LICM-NEXT:  entry:
81 ; BRANCH_FORM_LICM-NEXT:    [[D_GW_FR:%.*]] = freeze i32 [[D]]
82 ; BRANCH_FORM_LICM-NEXT:    [[C_GW_FR:%.*]] = freeze i32 [[C]]
83 ; BRANCH_FORM_LICM-NEXT:    [[B_GW_FR:%.*]] = freeze i32 [[B]]
84 ; BRANCH_FORM_LICM-NEXT:    br label [[LOOP:%.*]]
85 ; BRANCH_FORM_LICM:       loop:
86 ; BRANCH_FORM_LICM-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[GUARDED:%.*]] ]
87 ; BRANCH_FORM_LICM-NEXT:    [[IV_NEXT]] = add i32 [[IV]], 1
88 ; BRANCH_FORM_LICM-NEXT:    [[C1:%.*]] = icmp ult i32 [[IV]], [[A]]
89 ; BRANCH_FORM_LICM-NEXT:    [[C2:%.*]] = icmp ult i32 [[IV]], [[B_GW_FR]]
90 ; BRANCH_FORM_LICM-NEXT:    [[WIDE_CHK:%.*]] = and i1 [[C1]], [[C2]]
91 ; BRANCH_FORM_LICM-NEXT:    [[C3:%.*]] = icmp ult i32 [[IV]], [[C_GW_FR]]
92 ; BRANCH_FORM_LICM-NEXT:    [[WIDE_CHK13:%.*]] = and i1 [[WIDE_CHK]], [[C3]]
93 ; BRANCH_FORM_LICM-NEXT:    [[C4:%.*]] = icmp ult i32 [[IV]], [[D_GW_FR]]
94 ; BRANCH_FORM_LICM-NEXT:    [[WIDE_CHK14:%.*]] = and i1 [[WIDE_CHK13]], [[C4]]
95 ; BRANCH_FORM_LICM-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
96 ; BRANCH_FORM_LICM-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDE_CHK14]], [[WIDENABLE_COND]]
97 ; BRANCH_FORM_LICM-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[GUARDED]], label [[DEOPT:%.*]], !prof [[PROF0:![0-9]+]]
98 ; BRANCH_FORM_LICM:       deopt:
99 ; BRANCH_FORM_LICM-NEXT:    call void (...) @llvm.experimental.deoptimize.isVoid() [ "deopt"() ]
100 ; BRANCH_FORM_LICM-NEXT:    ret void
101 ; BRANCH_FORM_LICM:       guarded:
102 ; BRANCH_FORM_LICM-NEXT:    [[WIDENABLE_COND3:%.*]] = call i1 @llvm.experimental.widenable.condition()
103 ; BRANCH_FORM_LICM-NEXT:    [[EXIPLICIT_GUARD_COND4:%.*]] = and i1 [[C2]], [[WIDENABLE_COND3]]
104 ; BRANCH_FORM_LICM-NEXT:    [[WIDENABLE_COND7:%.*]] = call i1 @llvm.experimental.widenable.condition()
105 ; BRANCH_FORM_LICM-NEXT:    [[EXIPLICIT_GUARD_COND8:%.*]] = and i1 [[C3]], [[WIDENABLE_COND7]]
106 ; BRANCH_FORM_LICM-NEXT:    [[WIDENABLE_COND11:%.*]] = call i1 @llvm.experimental.widenable.condition()
107 ; BRANCH_FORM_LICM-NEXT:    [[EXIPLICIT_GUARD_COND12:%.*]] = and i1 [[C4]], [[WIDENABLE_COND11]]
108 ; BRANCH_FORM_LICM-NEXT:    [[LOOP_COND:%.*]] = call i1 @cond()
109 ; BRANCH_FORM_LICM-NEXT:    br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
110 ; BRANCH_FORM_LICM:       exit:
111 ; BRANCH_FORM_LICM-NEXT:    ret void
113 entry:
114   br label %loop
116 loop:
117   %iv = phi i32 [0, %entry], [%iv.next, %loop]
118   %iv.next = add i32 %iv, 1
119   %c1 = icmp ult i32 %iv, %a
120   call void(i1, ...) @llvm.experimental.guard(i1 %c1) [ "deopt"() ]
121   %c2 = icmp ult i32 %iv, %b
122   call void(i1, ...) @llvm.experimental.guard(i1 %c2) [ "deopt"() ]
123   %c3 = icmp ult i32 %iv, %c
124   call void(i1, ...) @llvm.experimental.guard(i1 %c3) [ "deopt"() ]
125   %c4 = icmp ult i32 %iv, %d
126   call void(i1, ...) @llvm.experimental.guard(i1 %c4) [ "deopt"() ]
127   %loop_cond = call i1 @cond()
128   br i1 %loop_cond, label %loop, label %exit
130 exit:
131   ret void
134 declare void @llvm.experimental.guard(i1, ...)