Skip to content

Commit 46ab5f8

Browse files
committed
[CVP] Infer range return attribute
We already infer this in IPSCCP, but as that pass runs very early, it cannot make use of simplifications (in particular post-inline simplifications). This fixes most cases from #98946 (everything apart from f2 where the assume is dropped).
1 parent f1ff3a2 commit 46ab5f8

File tree

7 files changed

+51
-33
lines changed

7 files changed

+51
-33
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,11 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
12071207
static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
12081208
const SimplifyQuery &SQ) {
12091209
bool FnChanged = false;
1210+
std::optional<ConstantRange> RetRange;
1211+
if (F.hasExactDefinition() && F.getReturnType()->isIntOrIntVectorTy())
1212+
RetRange =
1213+
ConstantRange::getEmpty(F.getReturnType()->getScalarSizeInBits());
1214+
12101215
// Visiting in a pre-order depth-first traversal causes us to simplify early
12111216
// blocks before querying later blocks (which require us to analyze early
12121217
// blocks). Eagerly simplifying shallow blocks means there is strictly less
@@ -1277,6 +1282,11 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
12771282
// constant folding the return values of callees.
12781283
auto *RetVal = RI->getReturnValue();
12791284
if (!RetVal) break; // handle "ret void"
1285+
if (RetRange && !RetRange->isFullSet())
1286+
RetRange =
1287+
RetRange->unionWith(LVI->getConstantRange(RetVal, RI,
1288+
/*UndefAllowed=*/false));
1289+
12801290
if (isa<Constant>(RetVal)) break; // nothing to do
12811291
if (auto *C = getConstantAt(RetVal, RI, LVI)) {
12821292
++NumReturns;
@@ -1289,6 +1299,14 @@ static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
12891299
FnChanged |= BBChanged;
12901300
}
12911301

1302+
// Infer range attribute on return value.
1303+
if (RetRange && !RetRange->isFullSet()) {
1304+
Attribute RangeAttr = F.getRetAttribute(Attribute::Range);
1305+
if (RangeAttr.isValid())
1306+
RetRange = RetRange->intersectWith(RangeAttr.getRange());
1307+
if (!RetRange->isEmptySet() && !RetRange->isSingleElement())
1308+
F.addRangeRetAttr(*RetRange);
1309+
}
12921310
return FnChanged;
12931311
}
12941312

llvm/test/Transforms/CorrelatedValuePropagation/add.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ exit:
311311

312312
@limit = external global i32
313313
define i32 @test11(ptr %p, i32 %i) {
314-
; CHECK-LABEL: define i32 @test11(
314+
; CHECK-LABEL: define range(i32 0, 2147483645) i32 @test11(
315315
; CHECK-SAME: ptr [[P:%.*]], i32 [[I:%.*]]) {
316316
; CHECK-NEXT: [[LIMIT:%.*]] = load i32, ptr [[P]], align 4, !range [[RNG0:![0-9]+]]
317317
; CHECK-NEXT: [[WITHIN_1:%.*]] = icmp ugt i32 [[LIMIT]], [[I]]

llvm/test/Transforms/CorrelatedValuePropagation/ashr.ll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ exit:
159159

160160
; check that ashr of -1 or 0 is optimized away
161161
define i32 @test6(i32 %f, i32 %g) {
162-
; CHECK-LABEL: define i32 @test6(
162+
; CHECK-LABEL: define range(i32 -1, 1) i32 @test6(
163163
; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
164164
; CHECK-NEXT: [[ENTRY:.*:]]
165165
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[F]], 1
@@ -177,7 +177,7 @@ entry:
177177

178178
; same test as above with different numbers
179179
define i32 @test7(i32 %f, i32 %g) {
180-
; CHECK-LABEL: define i32 @test7(
180+
; CHECK-LABEL: define range(i32 -1, 1) i32 @test7(
181181
; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]]) {
182182
; CHECK-NEXT: [[ENTRY:.*:]]
183183
; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[F]], -2
@@ -197,7 +197,7 @@ entry:
197197

198198
; check that ashr of -2 or 1 is not optimized away
199199
define i32 @test8(i32 %f, i32 %g, i1 %s) {
200-
; CHECK-LABEL: define i32 @test8(
200+
; CHECK-LABEL: define range(i32 -2, 2) i32 @test8(
201201
; CHECK-SAME: i32 [[F:%.*]], i32 [[G:%.*]], i1 [[S:%.*]]) {
202202
; CHECK-NEXT: [[ENTRY:.*:]]
203203
; CHECK-NEXT: [[TMP0:%.*]] = ashr i32 -2, [[F]]
@@ -213,7 +213,7 @@ entry:
213213
}
214214

215215
define i32 @may_including_undef(i1 %c.1, i1 %c.2) {
216-
; CHECK-LABEL: define i32 @may_including_undef(
216+
; CHECK-LABEL: define range(i32 -1073741824, 1073741824) i32 @may_including_undef(
217217
; CHECK-SAME: i1 [[C_1:%.*]], i1 [[C_2:%.*]]) {
218218
; CHECK-NEXT: br i1 [[C_1]], label %[[TRUE_1:.*]], label %[[FALSE:.*]]
219219
; CHECK: [[TRUE_1]]:

llvm/test/Transforms/CorrelatedValuePropagation/basic.ll

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
; PR2581
44

55
define i32 @test1(i1 %C) {
6-
; CHECK-LABEL: define i32 @test1
6+
; CHECK-LABEL: define range(i32 10, 12) i32 @test1
77
; CHECK-SAME: (i1 [[C:%.*]]) {
88
; CHECK-NEXT: br i1 [[C]], label [[EXIT:%.*]], label [[BODY:%.*]]
99
; CHECK: body:
@@ -82,7 +82,7 @@ bb2:
8282

8383
; PR1757
8484
define i32 @test4(i32) {
85-
; CHECK-LABEL: define i32 @test4
85+
; CHECK-LABEL: define range(i32 0, 3) i32 @test4
8686
; CHECK-SAME: (i32 [[TMP0:%.*]]) {
8787
; CHECK-NEXT: EntryBlock:
8888
; CHECK-NEXT: [[DOTDEMORGAN:%.*]] = icmp sgt i32 [[TMP0]], 2
@@ -210,7 +210,7 @@ return:
210210
}
211211

212212
define i32 @switch1(i32 %s) {
213-
; CHECK-LABEL: define i32 @switch1
213+
; CHECK-LABEL: define range(i32 -1, 2) i32 @switch1
214214
; CHECK-SAME: (i32 [[S:%.*]]) {
215215
; CHECK-NEXT: entry:
216216
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[S]], 0
@@ -250,7 +250,7 @@ next:
250250
}
251251

252252
define i32 @switch2(i32 %s) {
253-
; CHECK-LABEL: define i32 @switch2
253+
; CHECK-LABEL: define range(i32 -1, 2) i32 @switch2
254254
; CHECK-SAME: (i32 [[S:%.*]]) {
255255
; CHECK-NEXT: entry:
256256
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0
@@ -284,7 +284,7 @@ next:
284284
}
285285

286286
define i32 @switch3(i32 %s) {
287-
; CHECK-LABEL: define i32 @switch3
287+
; CHECK-LABEL: define range(i32 -1, 2) i32 @switch3
288288
; CHECK-SAME: (i32 [[S:%.*]]) {
289289
; CHECK-NEXT: entry:
290290
; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[S]], 0
@@ -451,7 +451,7 @@ unreachable:
451451
}
452452

453453
define i32 @switch_range(i32 %cond) {
454-
; CHECK-LABEL: define i32 @switch_range
454+
; CHECK-LABEL: define range(i32 1, 3) i32 @switch_range
455455
; CHECK-SAME: (i32 [[COND:%.*]]) {
456456
; CHECK-NEXT: entry:
457457
; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3
@@ -491,7 +491,7 @@ unreachable:
491491
; switch condition, we should not change the default.
492492

493493
define i32 @switch_range_not_full(i32 %cond) {
494-
; CHECK-LABEL: define i32 @switch_range_not_full
494+
; CHECK-LABEL: define range(i32 0, 3) i32 @switch_range_not_full
495495
; CHECK-SAME: (i32 [[COND:%.*]]) {
496496
; CHECK-NEXT: entry:
497497
; CHECK-NEXT: [[S:%.*]] = urem i32 [[COND]], 3
@@ -2052,7 +2052,7 @@ define i1 @binop_eval_order(i32 %x) {
20522052
}
20532053

20542054
define range(i32 0, 1024) i32 @range_larger(i8 %x) {
2055-
; CHECK-LABEL: define range(i32 0, 1024) i32 @range_larger
2055+
; CHECK-LABEL: define range(i32 0, 256) i32 @range_larger
20562056
; CHECK-SAME: (i8 [[X:%.*]]) {
20572057
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
20582058
; CHECK-NEXT: ret i32 [[ZEXT]]
@@ -2072,7 +2072,7 @@ define range(i32 0, 128) i32 @range_smaller(i8 %x) {
20722072
}
20732073

20742074
define range(i32 128, 512) i32 @range_intersect(i8 %x) {
2075-
; CHECK-LABEL: define range(i32 128, 512) i32 @range_intersect
2075+
; CHECK-LABEL: define range(i32 128, 256) i32 @range_intersect
20762076
; CHECK-SAME: (i8 [[X:%.*]]) {
20772077
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[X]] to i32
20782078
; CHECK-NEXT: ret i32 [[ZEXT]]

llvm/test/Transforms/CorrelatedValuePropagation/cond-using-block-value.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ end:
3838
}
3939

4040
define i64 @test_sext_from_implied_cond(i32 %a, i32 %b) {
41-
; CHECK-LABEL: define i64 @test_sext_from_implied_cond(
41+
; CHECK-LABEL: define range(i64 0, 2147483647) i64 @test_sext_from_implied_cond(
4242
; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]]) {
4343
; CHECK-NEXT: [[A_CMP:%.*]] = icmp slt i32 [[A]], 0
4444
; CHECK-NEXT: br i1 [[A_CMP]], label [[END:%.*]], label [[L1:%.*]]

llvm/test/Transforms/CorrelatedValuePropagation/select.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ else:
141141
}
142142

143143
define i8 @not_correlated(i1, i1) {
144-
; CHECK-LABEL: define i8 @not_correlated
144+
; CHECK-LABEL: define range(i8 0, 2) i8 @not_correlated
145145
; CHECK-SAME: (i1 [[TMP0:%.*]], i1 [[TMP1:%.*]]) {
146146
; CHECK-NEXT: entry:
147147
; CHECK-NEXT: [[S:%.*]] = select i1 [[TMP0]], i8 0, i8 1
@@ -361,7 +361,7 @@ exit:
361361
}
362362

363363
define i64 @select_cond_may_undef(i32 %a) {
364-
; CHECK-LABEL: define i64 @select_cond_may_undef
364+
; CHECK-LABEL: define range(i64 -2147483648, 2147483648) i64 @select_cond_may_undef
365365
; CHECK-SAME: (i32 [[A:%.*]]) {
366366
; CHECK-NEXT: [[IS_A_NONNEGATIVE:%.*]] = icmp sgt i32 [[A]], 1
367367
; CHECK-NEXT: [[NARROW:%.*]] = select i1 [[IS_A_NONNEGATIVE]], i32 [[A]], i32 0

llvm/test/Transforms/CorrelatedValuePropagation/vectors.ll

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ define <2 x i1> @cmp_signedness(<2 x i8> %a) {
6060
}
6161

6262
define <2 x i16> @infer_nowrap(<2 x i8> %a) {
63-
; CHECK-LABEL: define <2 x i16> @infer_nowrap(
63+
; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap(
6464
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
6565
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
6666
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 1>
@@ -72,7 +72,7 @@ define <2 x i16> @infer_nowrap(<2 x i8> %a) {
7272
}
7373

7474
define <2 x i16> @infer_nowrap_nonsplat(<2 x i8> %a) {
75-
; CHECK-LABEL: define <2 x i16> @infer_nowrap_nonsplat(
75+
; CHECK-LABEL: define range(i16 1, 258) <2 x i16> @infer_nowrap_nonsplat(
7676
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
7777
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
7878
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 2>
@@ -84,7 +84,7 @@ define <2 x i16> @infer_nowrap_nonsplat(<2 x i8> %a) {
8484
}
8585

8686
define <vscale x 2 x i16> @infer_nowrap_scalable(<vscale x 2 x i8> %a) {
87-
; CHECK-LABEL: define <vscale x 2 x i16> @infer_nowrap_scalable(
87+
; CHECK-LABEL: define range(i16 1, 257) <vscale x 2 x i16> @infer_nowrap_scalable(
8888
; CHECK-SAME: <vscale x 2 x i8> [[A:%.*]]) {
8989
; CHECK-NEXT: [[ZEXT:%.*]] = zext <vscale x 2 x i8> [[A]] to <vscale x 2 x i16>
9090
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <vscale x 2 x i16> [[ZEXT]], shufflevector (<vscale x 2 x i16> insertelement (<vscale x 2 x i16> poison, i16 1, i64 0), <vscale x 2 x i16> poison, <vscale x 2 x i32> zeroinitializer)
@@ -96,7 +96,7 @@ define <vscale x 2 x i16> @infer_nowrap_scalable(<vscale x 2 x i8> %a) {
9696
}
9797

9898
define <2 x i16> @infer_nowrap_poison(<2 x i8> %a) {
99-
; CHECK-LABEL: define <2 x i16> @infer_nowrap_poison(
99+
; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @infer_nowrap_poison(
100100
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
101101
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
102102
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 poison>
@@ -108,7 +108,7 @@ define <2 x i16> @infer_nowrap_poison(<2 x i8> %a) {
108108
}
109109

110110
define <2 x i16> @infer_nowrap_nonsplat_nsw_only(<2 x i8> %a) {
111-
; CHECK-LABEL: define <2 x i16> @infer_nowrap_nonsplat_nsw_only(
111+
; CHECK-LABEL: define range(i16 -1, 257) <2 x i16> @infer_nowrap_nonsplat_nsw_only(
112112
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
113113
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
114114
; CHECK-NEXT: [[RES:%.*]] = add nsw <2 x i16> [[ZEXT]], <i16 1, i16 -1>
@@ -120,7 +120,7 @@ define <2 x i16> @infer_nowrap_nonsplat_nsw_only(<2 x i8> %a) {
120120
}
121121

122122
define <2 x i16> @abs(<2 x i8> %a) {
123-
; CHECK-LABEL: define <2 x i16> @abs(
123+
; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @abs(
124124
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
125125
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
126126
; CHECK-NEXT: ret <2 x i16> [[ZEXT]]
@@ -131,7 +131,7 @@ define <2 x i16> @abs(<2 x i8> %a) {
131131
}
132132

133133
define <2 x i16> @saturating(<2 x i8> %a) {
134-
; CHECK-LABEL: define <2 x i16> @saturating(
134+
; CHECK-LABEL: define range(i16 1, 257) <2 x i16> @saturating(
135135
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
136136
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
137137
; CHECK-NEXT: [[RES:%.*]] = add nuw nsw <2 x i16> [[ZEXT]], <i16 1, i16 1>
@@ -156,7 +156,7 @@ define {<2 x i16>, <2 x i1>} @with_overflow(<2 x i8> %a) {
156156
}
157157

158158
define <2 x i16> @srem1(<2 x i8> %a) {
159-
; CHECK-LABEL: define <2 x i16> @srem1(
159+
; CHECK-LABEL: define range(i16 0, 42) <2 x i16> @srem1(
160160
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
161161
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
162162
; CHECK-NEXT: [[RES1_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>
@@ -170,7 +170,7 @@ define <2 x i16> @srem1(<2 x i8> %a) {
170170
}
171171

172172
define <2 x i16> @srem2(<2 x i8> %a) {
173-
; CHECK-LABEL: define <2 x i16> @srem2(
173+
; CHECK-LABEL: define range(i16 -41, 42) <2 x i16> @srem2(
174174
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
175175
; CHECK-NEXT: [[ZEXT:%.*]] = sext <2 x i8> [[A]] to <2 x i16>
176176
; CHECK-NEXT: [[RES_LHS_TRUNC:%.*]] = trunc <2 x i16> [[ZEXT]] to <2 x i8>
@@ -184,7 +184,7 @@ define <2 x i16> @srem2(<2 x i8> %a) {
184184
}
185185

186186
define <2 x i16> @ashr(<2 x i8> %a) {
187-
; CHECK-LABEL: define <2 x i16> @ashr(
187+
; CHECK-LABEL: define range(i16 0, 128) <2 x i16> @ashr(
188188
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
189189
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
190190
; CHECK-NEXT: [[RES:%.*]] = lshr <2 x i16> [[ZEXT]], <i16 1, i16 1>
@@ -196,7 +196,7 @@ define <2 x i16> @ashr(<2 x i8> %a) {
196196
}
197197

198198
define <2 x i32> @sext(<2 x i8> %a) {
199-
; CHECK-LABEL: define <2 x i32> @sext(
199+
; CHECK-LABEL: define range(i32 0, 256) <2 x i32> @sext(
200200
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
201201
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
202202
; CHECK-NEXT: [[RES:%.*]] = zext nneg <2 x i16> [[ZEXT]] to <2 x i32>
@@ -220,7 +220,7 @@ define <2 x float> @sitofp(<2 x i8> %a) {
220220
}
221221

222222
define <2 x i16> @and(<2 x i8> %a) {
223-
; CHECK-LABEL: define <2 x i16> @and(
223+
; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and(
224224
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
225225
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
226226
; CHECK-NEXT: ret <2 x i16> [[ZEXT]]
@@ -231,7 +231,7 @@ define <2 x i16> @and(<2 x i8> %a) {
231231
}
232232

233233
define <2 x i16> @and_with_poison(<2 x i8> %a) {
234-
; CHECK-LABEL: define <2 x i16> @and_with_poison(
234+
; CHECK-LABEL: define range(i16 0, 256) <2 x i16> @and_with_poison(
235235
; CHECK-SAME: <2 x i8> [[A:%.*]]) {
236236
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
237237
; CHECK-NEXT: ret <2 x i16> [[ZEXT]]
@@ -242,7 +242,7 @@ define <2 x i16> @and_with_poison(<2 x i8> %a) {
242242
}
243243

244244
define <4 x i64> @issue_97674_getConstantOnEdge(i1 %cond) {
245-
; CHECK-LABEL: define <4 x i64> @issue_97674_getConstantOnEdge(
245+
; CHECK-LABEL: define range(i64 0, 2) <4 x i64> @issue_97674_getConstantOnEdge(
246246
; CHECK-SAME: i1 [[COND:%.*]]) {
247247
; CHECK-NEXT: [[ENTRY:.*]]:
248248
; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
@@ -277,7 +277,7 @@ entry:
277277
}
278278

279279
define <2 x i16> @phi_merge1(i1 %c, <2 x i8> %a) {
280-
; CHECK-LABEL: define <2 x i16> @phi_merge1(
280+
; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge1(
281281
; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {
282282
; CHECK-NEXT: [[ENTRY:.*]]:
283283
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>
@@ -303,7 +303,7 @@ join:
303303
}
304304

305305
define <2 x i16> @phi_merge2(i1 %c, <2 x i8> %a) {
306-
; CHECK-LABEL: define <2 x i16> @phi_merge2(
306+
; CHECK-LABEL: define range(i16 2, 259) <2 x i16> @phi_merge2(
307307
; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]]) {
308308
; CHECK-NEXT: [[ENTRY:.*]]:
309309
; CHECK-NEXT: [[ZEXT:%.*]] = zext <2 x i8> [[A]] to <2 x i16>

0 commit comments

Comments
 (0)