[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / call-guard.ll
blobe3f678604103ff93d653c2e28fbf813b20d695d0
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -instcombine-infinite-loop-threshold=2 -S | FileCheck %s
3 ; RUN: opt < %s -instcombine -S -debugify-each | FileCheck %s
4 ; RUN: opt < %s -passes=instcombine -S -debugify-each | FileCheck %s
6 declare void @llvm.experimental.guard(i1, ...)
8 define void @test_guard_adjacent_same_cond(i1 %A) {
9 ; CHECK-LABEL: @test_guard_adjacent_same_cond(
10 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[A:%.*]]) [ "deopt"() ]
11 ; CHECK-NEXT:    ret void
13   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
14   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
15   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
16   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
17   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
18   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
19   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
20   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
21   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
22   call void(i1, ...) @llvm.experimental.guard( i1 %A )[ "deopt"() ]
23   ret void
26 define void @test_guard_adjacent_diff_cond(i1 %A, i1 %B, i1 %C) {
27 ; CHECK-LABEL: @test_guard_adjacent_diff_cond(
28 ; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
29 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[C:%.*]]
30 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 123) [ "deopt"() ]
31 ; CHECK-NEXT:    ret void
33   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
34   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
35   call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ]
36   ret void
39 ; This version tests for the common form where the conditions are
40 ; between the guards
41 define void @test_guard_adjacent_diff_cond2(i32 %V1, i32 %V2) {
42 ; CHECK-LABEL: @test_guard_adjacent_diff_cond2(
43 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[V1:%.*]], [[V2:%.*]]
44 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
45 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[V1]], 255
46 ; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[AND]], 129
47 ; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[C]]
48 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP3]], i32 123) [ "deopt"() ]
49 ; CHECK-NEXT:    ret void
51   %A = icmp slt i32 %V1, 0
52   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
53   %B = icmp slt i32 %V2, 0
54   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
55   %and = and i32 %V1, 255
56   %C = icmp sle i32 %and, 128
57   call void(i1, ...) @llvm.experimental.guard( i1 %C, i32 789 )[ "deopt"() ]
58   ret void
61 ; Might not be legal to hoist the load above the first guard since the
62 ; guard might control dereferenceability
63 define void @negative_load(i32 %V1, i32* %P) {
64 ; CHECK-LABEL: @negative_load(
65 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[V1:%.*]], 0
66 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[A]], i32 123) [ "deopt"() ]
67 ; CHECK-NEXT:    [[V2:%.*]] = load i32, i32* [[P:%.*]], align 4
68 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[V2]], 0
69 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[B]], i32 456) [ "deopt"() ]
70 ; CHECK-NEXT:    ret void
72   %A = icmp slt i32 %V1, 0
73   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
74   %V2 = load i32, i32* %P
75   %B = icmp slt i32 %V2, 0
76   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
77   ret void
80 define void @deref_load(i32 %V1, i32* dereferenceable(4) align 4 %P) nofree nosync {
81 ; CHECK-LABEL: @deref_load(
82 ; CHECK-NEXT:    [[V2:%.*]] = load i32, i32* [[P:%.*]], align 4
83 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[V2]], [[V1:%.*]]
84 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
85 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[TMP2]], i32 123) [ "deopt"() ]
86 ; CHECK-NEXT:    ret void
88   %A = icmp slt i32 %V1, 0
89   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
90   %V2 = load i32, i32* %P
91   %B = icmp slt i32 %V2, 0
92   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
93   ret void
96 ; The divide might fault above the guard
97 define void @negative_div(i32 %V1, i32 %D) {
98 ; CHECK-LABEL: @negative_div(
99 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[V1:%.*]], 0
100 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[A]], i32 123) [ "deopt"() ]
101 ; CHECK-NEXT:    [[V2:%.*]] = udiv i32 [[V1]], [[D:%.*]]
102 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[V2]], 0
103 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[B]], i32 456) [ "deopt"() ]
104 ; CHECK-NEXT:    ret void
106   %A = icmp slt i32 %V1, 0
107   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
108   %V2 = udiv i32 %V1, %D
109   %B = icmp slt i32 %V2, 0
110   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
111   ret void
114 ; Highlight the limit of the window in a case which would otherwise be mergable
115 define void @negative_window(i32 %V1, i32 %a, i32 %b, i32 %c, i32 %d) {
116 ; CHECK-LABEL: @negative_window(
117 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[V1:%.*]], 0
118 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[A]], i32 123) [ "deopt"() ]
119 ; CHECK-NEXT:    [[V2:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
120 ; CHECK-NEXT:    [[V3:%.*]] = add i32 [[V2]], [[C:%.*]]
121 ; CHECK-NEXT:    [[V4:%.*]] = add i32 [[V3]], [[D:%.*]]
122 ; CHECK-NEXT:    [[B:%.*]] = icmp slt i32 [[V4]], 0
123 ; CHECK-NEXT:    call void (i1, ...) @llvm.experimental.guard(i1 [[B]], i32 456) [ "deopt"() ]
124 ; CHECK-NEXT:    ret void
126   %A = icmp slt i32 %V1, 0
127   call void(i1, ...) @llvm.experimental.guard( i1 %A, i32 123 )[ "deopt"() ]
128   %V2 = add i32 %a, %b
129   %V3 = add i32 %V2, %c
130   %V4 = add i32 %V3, %d
131   %B = icmp slt i32 %V4, 0
132   call void(i1, ...) @llvm.experimental.guard( i1 %B, i32 456 )[ "deopt"() ]
133   ret void