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