|
2 | 2 | ; RUN: opt -constraint-elimination -S %s | FileCheck %s
|
3 | 3 |
|
4 | 4 | define i1 @bitcast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) {
|
5 |
| -; |
6 | 5 | ; CHECK-LABEL: @bitcast_and_cmp(
|
7 | 6 | ; CHECK-NEXT: check.0.min:
|
8 | 7 | ; CHECK-NEXT: [[SRC_C:%.*]] = bitcast i32* [[SRC:%.*]] to i8*
|
@@ -79,3 +78,159 @@ checks:
|
79 | 78 |
|
80 | 79 | ret i1 %res.7
|
81 | 80 | }
|
| 81 | + |
| 82 | +define i1 @gep0_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) { |
| 83 | +; CHECK-LABEL: @gep0_and_cmp( |
| 84 | +; CHECK-NEXT: check.0.min: |
| 85 | +; CHECK-NEXT: [[SRC_C:%.*]] = getelementptr i32, i32* [[SRC:%.*]], i64 0 |
| 86 | +; CHECK-NEXT: [[MIN_C:%.*]] = getelementptr i32, i32* [[MIN:%.*]], i64 0 |
| 87 | +; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 |
| 88 | +; CHECK-NEXT: [[GEP_3_C:%.*]] = getelementptr i32, i32* [[GEP_3]], i32 0 |
| 89 | +; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i32* [[SRC_C]], [[MIN_C]] |
| 90 | +; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i32* [[GEP_3_C]], [[MAX:%.*]] |
| 91 | +; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]] |
| 92 | +; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]] |
| 93 | +; CHECK: trap: |
| 94 | +; CHECK-NEXT: ret i1 false |
| 95 | +; CHECK: checks: |
| 96 | +; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]] |
| 97 | +; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]] |
| 98 | +; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]] |
| 99 | +; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 |
| 100 | +; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]] |
| 101 | +; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]] |
| 102 | +; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true |
| 103 | +; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 |
| 104 | +; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]] |
| 105 | +; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]] |
| 106 | +; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true |
| 107 | +; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4 |
| 108 | +; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]] |
| 109 | +; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]] |
| 110 | +; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]] |
| 111 | +; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]] |
| 112 | +; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]] |
| 113 | +; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]] |
| 114 | +; CHECK-NEXT: ret i1 [[RES_7]] |
| 115 | +; |
| 116 | +check.0.min: |
| 117 | + %src.c = getelementptr i32, i32* %src, i64 0 |
| 118 | + %min.c = getelementptr i32, i32* %min, i64 0 |
| 119 | + |
| 120 | + %gep.3 = getelementptr inbounds i32, i32* %src, i64 3 |
| 121 | + %gep.3.c = getelementptr i32, i32* %gep.3, i32 0 |
| 122 | + %c.min.0 = icmp ult i32* %src.c, %min.c |
| 123 | + %c.max.3 = icmp ugt i32* %gep.3.c, %max |
| 124 | + |
| 125 | + %or = or i1 %c.min.0, %c.max.3 |
| 126 | + br i1 %or, label %trap, label %checks |
| 127 | + |
| 128 | +trap: |
| 129 | + ret i1 0 |
| 130 | + |
| 131 | +checks: |
| 132 | + %c.3.min = icmp ult i32* %gep.3, %min |
| 133 | + %c.3.max = icmp ult i32* %gep.3, %max |
| 134 | + %res.1 = xor i1 %c.3.min, %c.3.max |
| 135 | + |
| 136 | + %gep.1 = getelementptr inbounds i32, i32* %src, i64 1 |
| 137 | + %c.1.min = icmp ult i32* %gep.1, %min |
| 138 | + %c.1.max = icmp ult i32* %gep.1, %max |
| 139 | + %res.2 = xor i1 %c.1.min, %c.1.max |
| 140 | + |
| 141 | + %gep.2 = getelementptr inbounds i32, i32* %src, i64 2 |
| 142 | + %c.2.min = icmp ult i32* %gep.2, %min |
| 143 | + %c.2.max = icmp ult i32* %gep.2, %max |
| 144 | + %res.3 = xor i1 %c.2.min, %c.2.max |
| 145 | + |
| 146 | + %gep.4 = getelementptr inbounds i32, i32* %src, i64 4 |
| 147 | + %c.4.min = icmp ult i32* %gep.4, %min |
| 148 | + %c.4.max = icmp ult i32* %gep.4, %max |
| 149 | + %res.4 = xor i1 %c.4.min, %c.4.max |
| 150 | + |
| 151 | + %res.5 = xor i1 %res.1, %res.2 |
| 152 | + %res.6 = xor i1 %res.5, %res.3 |
| 153 | + %res.7 = xor i1 %res.6, %res.4 |
| 154 | + |
| 155 | + ret i1 %res.7 |
| 156 | +} |
| 157 | + |
| 158 | +; Should not look through addresspacecast, because it may change the pointer |
| 159 | +; value. |
| 160 | +define i1 @addrspacecast_and_cmp(i32* readonly %src, i32* readnone %min, i32* readnone %max) { |
| 161 | +; CHECK-LABEL: @addrspacecast_and_cmp( |
| 162 | +; CHECK-NEXT: check.0.min: |
| 163 | +; CHECK-NEXT: [[SRC_C:%.*]] = addrspacecast i32* [[SRC:%.*]] to i8 addrspace(1)* |
| 164 | +; CHECK-NEXT: [[MIN_C:%.*]] = addrspacecast i32* [[MIN:%.*]] to i8 addrspace(1)* |
| 165 | +; CHECK-NEXT: [[MAX_C:%.*]] = addrspacecast i32* [[MAX:%.*]] to i16 addrspace(1)* |
| 166 | +; CHECK-NEXT: [[GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 |
| 167 | +; CHECK-NEXT: [[GEP_3_C:%.*]] = addrspacecast i32* [[GEP_3]] to i16 addrspace(1)* |
| 168 | +; CHECK-NEXT: [[C_MIN_0:%.*]] = icmp ult i8 addrspace(1)* [[SRC_C]], [[MIN_C]] |
| 169 | +; CHECK-NEXT: [[C_MAX_3:%.*]] = icmp ugt i16 addrspace(1)* [[GEP_3_C]], [[MAX_C]] |
| 170 | +; CHECK-NEXT: [[OR:%.*]] = or i1 [[C_MIN_0]], [[C_MAX_3]] |
| 171 | +; CHECK-NEXT: br i1 [[OR]], label [[TRAP:%.*]], label [[CHECKS:%.*]] |
| 172 | +; CHECK: trap: |
| 173 | +; CHECK-NEXT: ret i1 false |
| 174 | +; CHECK: checks: |
| 175 | +; CHECK-NEXT: [[C_3_MIN:%.*]] = icmp ult i32* [[GEP_3]], [[MIN]] |
| 176 | +; CHECK-NEXT: [[C_3_MAX:%.*]] = icmp ult i32* [[GEP_3]], [[MAX]] |
| 177 | +; CHECK-NEXT: [[RES_1:%.*]] = xor i1 false, [[C_3_MAX]] |
| 178 | +; CHECK-NEXT: [[GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 |
| 179 | +; CHECK-NEXT: [[C_1_MIN:%.*]] = icmp ult i32* [[GEP_1]], [[MIN]] |
| 180 | +; CHECK-NEXT: [[C_1_MAX:%.*]] = icmp ult i32* [[GEP_1]], [[MAX]] |
| 181 | +; CHECK-NEXT: [[RES_2:%.*]] = xor i1 false, true |
| 182 | +; CHECK-NEXT: [[GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 |
| 183 | +; CHECK-NEXT: [[C_2_MIN:%.*]] = icmp ult i32* [[GEP_2]], [[MIN]] |
| 184 | +; CHECK-NEXT: [[C_2_MAX:%.*]] = icmp ult i32* [[GEP_2]], [[MAX]] |
| 185 | +; CHECK-NEXT: [[RES_3:%.*]] = xor i1 false, true |
| 186 | +; CHECK-NEXT: [[GEP_4:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 4 |
| 187 | +; CHECK-NEXT: [[C_4_MIN:%.*]] = icmp ult i32* [[GEP_4]], [[MIN]] |
| 188 | +; CHECK-NEXT: [[C_4_MAX:%.*]] = icmp ult i32* [[GEP_4]], [[MAX]] |
| 189 | +; CHECK-NEXT: [[RES_4:%.*]] = xor i1 false, [[C_4_MAX]] |
| 190 | +; CHECK-NEXT: [[RES_5:%.*]] = xor i1 [[RES_1]], [[RES_2]] |
| 191 | +; CHECK-NEXT: [[RES_6:%.*]] = xor i1 [[RES_5]], [[RES_3]] |
| 192 | +; CHECK-NEXT: [[RES_7:%.*]] = xor i1 [[RES_6]], [[RES_4]] |
| 193 | +; CHECK-NEXT: ret i1 [[RES_7]] |
| 194 | +; |
| 195 | +check.0.min: |
| 196 | + %src.c = addrspacecast i32* %src to i8 addrspace(1)* |
| 197 | + %min.c = addrspacecast i32* %min to i8 addrspace(1)* |
| 198 | + %max.c = addrspacecast i32* %max to i16 addrspace(1)* |
| 199 | + |
| 200 | + %gep.3 = getelementptr inbounds i32, i32* %src, i64 3 |
| 201 | + %gep.3.c = addrspacecast i32* %gep.3 to i16 addrspace(1) * |
| 202 | + %c.min.0 = icmp ult i8 addrspace(1)* %src.c, %min.c |
| 203 | + %c.max.3 = icmp ugt i16 addrspace(1)* %gep.3.c, %max.c |
| 204 | + |
| 205 | + %or = or i1 %c.min.0, %c.max.3 |
| 206 | + br i1 %or, label %trap, label %checks |
| 207 | + |
| 208 | +trap: |
| 209 | + ret i1 0 |
| 210 | + |
| 211 | +checks: |
| 212 | + %c.3.min = icmp ult i32* %gep.3, %min |
| 213 | + %c.3.max = icmp ult i32* %gep.3, %max |
| 214 | + %res.1 = xor i1 %c.3.min, %c.3.max |
| 215 | + |
| 216 | + %gep.1 = getelementptr inbounds i32, i32* %src, i64 1 |
| 217 | + %c.1.min = icmp ult i32* %gep.1, %min |
| 218 | + %c.1.max = icmp ult i32* %gep.1, %max |
| 219 | + %res.2 = xor i1 %c.1.min, %c.1.max |
| 220 | + |
| 221 | + %gep.2 = getelementptr inbounds i32, i32* %src, i64 2 |
| 222 | + %c.2.min = icmp ult i32* %gep.2, %min |
| 223 | + %c.2.max = icmp ult i32* %gep.2, %max |
| 224 | + %res.3 = xor i1 %c.2.min, %c.2.max |
| 225 | + |
| 226 | + %gep.4 = getelementptr inbounds i32, i32* %src, i64 4 |
| 227 | + %c.4.min = icmp ult i32* %gep.4, %min |
| 228 | + %c.4.max = icmp ult i32* %gep.4, %max |
| 229 | + %res.4 = xor i1 %c.4.min, %c.4.max |
| 230 | + |
| 231 | + %res.5 = xor i1 %res.1, %res.2 |
| 232 | + %res.6 = xor i1 %res.5, %res.3 |
| 233 | + %res.7 = xor i1 %res.6, %res.4 |
| 234 | + |
| 235 | + ret i1 %res.7 |
| 236 | +} |
0 commit comments