Mercurial > hg > CbC > CbC_llvm
comparison llvm/test/Transforms/IndVarSimplify/ashr-expansion.ll @ 252:1f2b6ac9f198 llvm-original
LLVM16-1
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 18 Aug 2023 09:04:13 +0900 |
parents | c4bab56944e8 |
children |
comparison
equal
deleted
inserted
replaced
237:c80f45b162ad | 252:1f2b6ac9f198 |
---|---|
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | 1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
2 ; RUN: opt -passes=indvars -S %s | FileCheck %s | 2 ; RUN: opt -passes=indvars -S %s | FileCheck %s |
3 | 3 |
4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" | 4 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" |
5 | 5 |
6 define float @ashr_expansion_valid(i64 %x, float* %ptr) { | 6 define float @ashr_expansion_valid(i64 %x, ptr %ptr) { |
7 ; CHECK-LABEL: @ashr_expansion_valid( | 7 ; CHECK-LABEL: @ashr_expansion_valid( |
8 ; CHECK-NEXT: entry: | 8 ; CHECK-NEXT: entry: |
9 ; CHECK-NEXT: [[BOUND:%.*]] = ashr exact i64 [[X:%.*]], 4 | 9 ; CHECK-NEXT: [[BOUND:%.*]] = ashr exact i64 [[X:%.*]], 4 |
10 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) | 10 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) |
11 ; CHECK-NEXT: br label [[LOOP:%.*]] | 11 ; CHECK-NEXT: br label [[LOOP:%.*]] |
12 ; CHECK: loop: | 12 ; CHECK: loop: |
13 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] | 13 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] |
14 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] | 14 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] |
15 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, float* [[PTR:%.*]], i64 [[IV]] | 15 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, ptr [[PTR:%.*]], i64 [[IV]] |
16 ; CHECK-NEXT: [[LV:%.*]] = load float, float* [[GEP]], align 4 | 16 ; CHECK-NEXT: [[LV:%.*]] = load float, ptr [[GEP]], align 4 |
17 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] | 17 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] |
18 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 | 18 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 |
19 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] | 19 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] |
20 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] | 20 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] |
21 ; CHECK: exit: | 21 ; CHECK: exit: |
27 br label %loop | 27 br label %loop |
28 | 28 |
29 loop: | 29 loop: |
30 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | 30 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
31 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] | 31 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] |
32 %gep = getelementptr float, float* %ptr, i64 %iv | 32 %gep = getelementptr float, ptr %ptr, i64 %iv |
33 %lv = load float, float* %gep | 33 %lv = load float, ptr %gep |
34 %red.next = fadd float %lv, %red | 34 %red.next = fadd float %lv, %red |
35 %iv.next = add nuw i64 %iv, 1 | 35 %iv.next = add nuw i64 %iv, 1 |
36 %cond = icmp ult i64 %iv.next, %bound | 36 %cond = icmp ult i64 %iv.next, %bound |
37 br i1 %cond, label %loop, label %exit | 37 br i1 %cond, label %loop, label %exit |
38 | 38 |
40 %lcssa.red.next = phi float [ %red.next, %loop ] | 40 %lcssa.red.next = phi float [ %red.next, %loop ] |
41 ret float %lcssa.red.next | 41 ret float %lcssa.red.next |
42 } | 42 } |
43 | 43 |
44 ; No explicit ashr, but a chain of operations that can be replaced by ashr. | 44 ; No explicit ashr, but a chain of operations that can be replaced by ashr. |
45 define float @ashr_equivalent_expansion(i64 %x, float* %ptr) { | 45 define float @ashr_equivalent_expansion(i64 %x, ptr %ptr) { |
46 ; CHECK-LABEL: @ashr_equivalent_expansion( | 46 ; CHECK-LABEL: @ashr_equivalent_expansion( |
47 ; CHECK-NEXT: entry: | 47 ; CHECK-NEXT: entry: |
48 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) | 48 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) |
49 ; CHECK-NEXT: [[DIV:%.*]] = udiv exact i64 [[ABS_X]], 16 | 49 ; CHECK-NEXT: [[DIV:%.*]] = udiv exact i64 [[ABS_X]], 16 |
50 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[X]], i64 -1) | 50 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[X]], i64 -1) |
53 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) | 53 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) |
54 ; CHECK-NEXT: br label [[LOOP:%.*]] | 54 ; CHECK-NEXT: br label [[LOOP:%.*]] |
55 ; CHECK: loop: | 55 ; CHECK: loop: |
56 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] | 56 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] |
57 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] | 57 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] |
58 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, float* [[PTR:%.*]], i64 [[IV]] | 58 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, ptr [[PTR:%.*]], i64 [[IV]] |
59 ; CHECK-NEXT: [[LV:%.*]] = load float, float* [[GEP]], align 4 | 59 ; CHECK-NEXT: [[LV:%.*]] = load float, ptr [[GEP]], align 4 |
60 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] | 60 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] |
61 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 | 61 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 |
62 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] | 62 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] |
63 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] | 63 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] |
64 ; CHECK: exit: | 64 ; CHECK: exit: |
74 br label %loop | 74 br label %loop |
75 | 75 |
76 loop: | 76 loop: |
77 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | 77 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
78 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] | 78 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] |
79 %gep = getelementptr float, float* %ptr, i64 %iv | 79 %gep = getelementptr float, ptr %ptr, i64 %iv |
80 %lv = load float, float* %gep | 80 %lv = load float, ptr %gep |
81 %red.next = fadd float %lv, %red | 81 %red.next = fadd float %lv, %red |
82 %iv.next = add nuw i64 %iv, 1 | 82 %iv.next = add nuw i64 %iv, 1 |
83 %cond = icmp ult i64 %iv.next, %bound | 83 %cond = icmp ult i64 %iv.next, %bound |
84 br i1 %cond, label %loop, label %exit | 84 br i1 %cond, label %loop, label %exit |
85 | 85 |
88 ret float %lcssa.red.next | 88 ret float %lcssa.red.next |
89 } | 89 } |
90 | 90 |
91 ; Chain of operations that *cannot* be replaced by ashr, because the udiv is | 91 ; Chain of operations that *cannot* be replaced by ashr, because the udiv is |
92 ; missing exact. | 92 ; missing exact. |
93 define float @no_ashr_due_to_missing_exact_udiv(i64 %x, float* %ptr) { | 93 define float @no_ashr_due_to_missing_exact_udiv(i64 %x, ptr %ptr) { |
94 ; CHECK-LABEL: @no_ashr_due_to_missing_exact_udiv( | 94 ; CHECK-LABEL: @no_ashr_due_to_missing_exact_udiv( |
95 ; CHECK-NEXT: entry: | 95 ; CHECK-NEXT: entry: |
96 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) | 96 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) |
97 ; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[ABS_X]], 16 | 97 ; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[ABS_X]], 16 |
98 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[X]], i64 -1) | 98 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[X]], i64 -1) |
101 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) | 101 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) |
102 ; CHECK-NEXT: br label [[LOOP:%.*]] | 102 ; CHECK-NEXT: br label [[LOOP:%.*]] |
103 ; CHECK: loop: | 103 ; CHECK: loop: |
104 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] | 104 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] |
105 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] | 105 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] |
106 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, float* [[PTR:%.*]], i64 [[IV]] | 106 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, ptr [[PTR:%.*]], i64 [[IV]] |
107 ; CHECK-NEXT: [[LV:%.*]] = load float, float* [[GEP]], align 4 | 107 ; CHECK-NEXT: [[LV:%.*]] = load float, ptr [[GEP]], align 4 |
108 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] | 108 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] |
109 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 | 109 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 |
110 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] | 110 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] |
111 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] | 111 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] |
112 ; CHECK: exit: | 112 ; CHECK: exit: |
122 br label %loop | 122 br label %loop |
123 | 123 |
124 loop: | 124 loop: |
125 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | 125 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
126 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] | 126 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] |
127 %gep = getelementptr float, float* %ptr, i64 %iv | 127 %gep = getelementptr float, ptr %ptr, i64 %iv |
128 %lv = load float, float* %gep | 128 %lv = load float, ptr %gep |
129 %red.next = fadd float %lv, %red | 129 %red.next = fadd float %lv, %red |
130 %iv.next = add nuw i64 %iv, 1 | 130 %iv.next = add nuw i64 %iv, 1 |
131 %cond = icmp ult i64 %iv.next, %bound | 131 %cond = icmp ult i64 %iv.next, %bound |
132 br i1 %cond, label %loop, label %exit | 132 br i1 %cond, label %loop, label %exit |
133 | 133 |
136 ret float %lcssa.red.next | 136 ret float %lcssa.red.next |
137 } | 137 } |
138 | 138 |
139 ; Chain of operations that *cannot* be replaced by ashr, because abs and | 139 ; Chain of operations that *cannot* be replaced by ashr, because abs and |
140 ; signum have different operands. | 140 ; signum have different operands. |
141 define float @no_ashr_due_to_different_ops(i64 %x, i64 %y, float* %ptr) { | 141 define float @no_ashr_due_to_different_ops(i64 %x, i64 %y, ptr %ptr) { |
142 ; CHECK-LABEL: @no_ashr_due_to_different_ops( | 142 ; CHECK-LABEL: @no_ashr_due_to_different_ops( |
143 ; CHECK-NEXT: entry: | 143 ; CHECK-NEXT: entry: |
144 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) | 144 ; CHECK-NEXT: [[ABS_X:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 false) |
145 ; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[ABS_X]], 16 | 145 ; CHECK-NEXT: [[DIV:%.*]] = udiv i64 [[ABS_X]], 16 |
146 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[Y:%.*]], i64 -1) | 146 ; CHECK-NEXT: [[T0:%.*]] = call i64 @llvm.smax.i64(i64 [[Y:%.*]], i64 -1) |
149 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) | 149 ; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[BOUND]], i64 1) |
150 ; CHECK-NEXT: br label [[LOOP:%.*]] | 150 ; CHECK-NEXT: br label [[LOOP:%.*]] |
151 ; CHECK: loop: | 151 ; CHECK: loop: |
152 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] | 152 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ] |
153 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] | 153 ; CHECK-NEXT: [[RED:%.*]] = phi float [ 0.000000e+00, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ] |
154 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, float* [[PTR:%.*]], i64 [[IV]] | 154 ; CHECK-NEXT: [[GEP:%.*]] = getelementptr float, ptr [[PTR:%.*]], i64 [[IV]] |
155 ; CHECK-NEXT: [[LV:%.*]] = load float, float* [[GEP]], align 4 | 155 ; CHECK-NEXT: [[LV:%.*]] = load float, ptr [[GEP]], align 4 |
156 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] | 156 ; CHECK-NEXT: [[RED_NEXT]] = fadd float [[LV]], [[RED]] |
157 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 | 157 ; CHECK-NEXT: [[IV_NEXT]] = add nuw i64 [[IV]], 1 |
158 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] | 158 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[IV_NEXT]], [[UMAX]] |
159 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] | 159 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[EXIT:%.*]] |
160 ; CHECK: exit: | 160 ; CHECK: exit: |
170 br label %loop | 170 br label %loop |
171 | 171 |
172 loop: | 172 loop: |
173 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | 173 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] |
174 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] | 174 %red = phi float [ 0.0, %entry ], [ %red.next, %loop ] |
175 %gep = getelementptr float, float* %ptr, i64 %iv | 175 %gep = getelementptr float, ptr %ptr, i64 %iv |
176 %lv = load float, float* %gep | 176 %lv = load float, ptr %gep |
177 %red.next = fadd float %lv, %red | 177 %red.next = fadd float %lv, %red |
178 %iv.next = add nuw i64 %iv, 1 | 178 %iv.next = add nuw i64 %iv, 1 |
179 %cond = icmp ult i64 %iv.next, %bound | 179 %cond = icmp ult i64 %iv.next, %bound |
180 br i1 %cond, label %loop, label %exit | 180 br i1 %cond, label %loop, label %exit |
181 | 181 |