Skip to content

Commit 377cb7f

Browse files
authored
[CIR] Upstream shift operators for VectorType (llvm#139465)
This change adds support for shift ops for VectorType Issue llvm#136487
1 parent 698fcb1 commit 377cb7f

File tree

6 files changed

+186
-35
lines changed

6 files changed

+186
-35
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,18 +1401,20 @@ def ShiftOp : CIR_Op<"shift", [Pure]> {
14011401
The `cir.shift` operation performs a bitwise shift, either to the left or to
14021402
the right, based on the first operand. The second operand specifies the
14031403
value to be shifted, and the third operand determines the number of
1404-
positions by which the shift is applied. Both the second and third operands
1405-
are required to be integers.
1404+
positions by which the shift is applied, They must be either all vector of
1405+
integer type, or all integer type. If they are vectors, each vector element of
1406+
the shift target is shifted by the corresponding shift amount in
1407+
the shift amount vector.
14061408

14071409
```mlir
1408-
%7 = cir.shift(left, %1 : !u64i, %4 : !s32i) -> !u64i
1410+
%res = cir.shift(left, %lhs : !u64i, %amount : !s32i) -> !u64i
1411+
%new_vec = cir.shift(left, %lhs : !cir.vector<2 x !s32i>, %rhs :
1412+
!cir.vector<2 x !s32i>) -> !cir.vector<2 x !s32i>
14091413
```
14101414
}];
14111415

1412-
// TODO(cir): Support vectors. CIR_IntType -> CIR_AnyIntOrVecOfInt. Also
1413-
// update the description above.
1414-
let results = (outs CIR_IntType:$result);
1415-
let arguments = (ins CIR_IntType:$value, CIR_IntType:$amount,
1416+
let results = (outs CIR_AnyIntOrVecOfInt:$result);
1417+
let arguments = (ins CIR_AnyIntOrVecOfInt:$value, CIR_AnyIntOrVecOfInt:$amount,
14161418
UnitAttr:$isShiftleft);
14171419

14181420
let assemblyFormat = [{

clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,23 @@ def CIR_PtrToVoidPtrType
174174
"$_builder.getType<" # cppType # ">("
175175
"cir::VoidType::get($_builder.getContext())))">;
176176

177+
//===----------------------------------------------------------------------===//
178+
// Vector Type predicates
179+
//===----------------------------------------------------------------------===//
180+
181+
// Vector of integral type
182+
def IntegerVector : Type<
183+
And<[
184+
CPred<"::mlir::isa<::cir::VectorType>($_self)">,
185+
CPred<"::mlir::isa<::cir::IntType>("
186+
"::mlir::cast<::cir::VectorType>($_self).getElementType())">,
187+
CPred<"::mlir::cast<::cir::IntType>("
188+
"::mlir::cast<::cir::VectorType>($_self).getElementType())"
189+
".isFundamental()">
190+
]>, "!cir.vector of !cir.int"> {
191+
}
192+
193+
// Any Integer or Vector of Integer Constraints
194+
def CIR_AnyIntOrVecOfInt: AnyTypeOf<[CIR_AnyIntType, IntegerVector]>;
195+
177196
#endif // CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,9 +1297,8 @@ OpFoldResult cir::SelectOp::fold(FoldAdaptor adaptor) {
12971297
LogicalResult cir::ShiftOp::verify() {
12981298
mlir::Operation *op = getOperation();
12991299
mlir::Type resType = getResult().getType();
1300-
assert(!cir::MissingFeatures::vectorType());
1301-
bool isOp0Vec = false;
1302-
bool isOp1Vec = false;
1300+
const bool isOp0Vec = mlir::isa<cir::VectorType>(op->getOperand(0).getType());
1301+
const bool isOp1Vec = mlir::isa<cir::VectorType>(op->getOperand(1).getType());
13031302
if (isOp0Vec != isOp1Vec)
13041303
return emitOpError() << "input types cannot be one vector and one scalar";
13051304
if (isOp1Vec && op->getOperand(1).getType() != resType) {

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,41 +1372,42 @@ mlir::LogicalResult CIRToLLVMCmpOpLowering::matchAndRewrite(
13721372
mlir::LogicalResult CIRToLLVMShiftOpLowering::matchAndRewrite(
13731373
cir::ShiftOp op, OpAdaptor adaptor,
13741374
mlir::ConversionPatternRewriter &rewriter) const {
1375-
auto cirAmtTy = mlir::dyn_cast<cir::IntType>(op.getAmount().getType());
1376-
auto cirValTy = mlir::dyn_cast<cir::IntType>(op.getValue().getType());
1375+
assert((op.getValue().getType() == op.getType()) &&
1376+
"inconsistent operands' types NYI");
13771377

1378-
// Operands could also be vector type
1379-
assert(!cir::MissingFeatures::vectorType());
1380-
mlir::Type llvmTy = getTypeConverter()->convertType(op.getType());
1378+
const mlir::Type llvmTy = getTypeConverter()->convertType(op.getType());
13811379
mlir::Value amt = adaptor.getAmount();
13821380
mlir::Value val = adaptor.getValue();
13831381

1384-
// TODO(cir): Assert for vector types
1385-
assert((cirValTy && cirAmtTy) &&
1386-
"shift input type must be integer or vector type, otherwise NYI");
1387-
1388-
assert((cirValTy == op.getType()) && "inconsistent operands' types NYI");
1389-
1390-
// Ensure shift amount is the same type as the value. Some undefined
1391-
// behavior might occur in the casts below as per [C99 6.5.7.3].
1392-
// Vector type shift amount needs no cast as type consistency is expected to
1393-
// be already be enforced at CIRGen.
1394-
if (cirAmtTy)
1395-
amt = getLLVMIntCast(rewriter, amt, mlir::cast<mlir::IntegerType>(llvmTy),
1396-
true, cirAmtTy.getWidth(), cirValTy.getWidth());
1382+
auto cirAmtTy = mlir::dyn_cast<cir::IntType>(op.getAmount().getType());
1383+
bool isUnsigned;
1384+
if (cirAmtTy) {
1385+
auto cirValTy = mlir::cast<cir::IntType>(op.getValue().getType());
1386+
isUnsigned = cirValTy.isUnsigned();
1387+
1388+
// Ensure shift amount is the same type as the value. Some undefined
1389+
// behavior might occur in the casts below as per [C99 6.5.7.3].
1390+
// Vector type shift amount needs no cast as type consistency is expected to
1391+
// be already be enforced at CIRGen.
1392+
if (cirAmtTy)
1393+
amt = getLLVMIntCast(rewriter, amt, llvmTy, true, cirAmtTy.getWidth(),
1394+
cirValTy.getWidth());
1395+
} else {
1396+
auto cirValVTy = mlir::cast<cir::VectorType>(op.getValue().getType());
1397+
isUnsigned =
1398+
mlir::cast<cir::IntType>(cirValVTy.getElementType()).isUnsigned();
1399+
}
13971400

13981401
// Lower to the proper LLVM shift operation.
13991402
if (op.getIsShiftleft()) {
14001403
rewriter.replaceOpWithNewOp<mlir::LLVM::ShlOp>(op, llvmTy, val, amt);
1401-
} else {
1402-
assert(!cir::MissingFeatures::vectorType());
1403-
bool isUnsigned = !cirValTy.isSigned();
1404-
if (isUnsigned)
1405-
rewriter.replaceOpWithNewOp<mlir::LLVM::LShrOp>(op, llvmTy, val, amt);
1406-
else
1407-
rewriter.replaceOpWithNewOp<mlir::LLVM::AShrOp>(op, llvmTy, val, amt);
1404+
return mlir::success();
14081405
}
14091406

1407+
if (isUnsigned)
1408+
rewriter.replaceOpWithNewOp<mlir::LLVM::LShrOp>(op, llvmTy, val, amt);
1409+
else
1410+
rewriter.replaceOpWithNewOp<mlir::LLVM::AShrOp>(op, llvmTy, val, amt);
14101411
return mlir::success();
14111412
}
14121413

clang/test/CIR/CodeGen/vector-ext.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,68 @@ void foo7() {
336336
// OGCG: %[[TMP2:.*]] = load <4 x i32>, ptr %[[VEC]], align 16
337337
// OGCG: %[[NEW_VEC:.*]] = insertelement <4 x i32> %[[TMP2]], i32 %[[RES]], i32 2
338338
// OGCG: store <4 x i32> %[[NEW_VEC]], ptr %[[VEC]], align 16
339+
340+
void foo9() {
341+
vi4 a = {1, 2, 3, 4};
342+
vi4 b = {5, 6, 7, 8};
343+
344+
vi4 shl = a << b;
345+
vi4 shr = a >> b;
346+
}
347+
348+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init]
349+
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["b", init]
350+
// CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shl", init]
351+
// CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shr", init]
352+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
353+
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
354+
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
355+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
356+
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
357+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
358+
// CIR: cir.store %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
359+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
360+
// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i
361+
// CIR: %[[CONST_7:.*]] = cir.const #cir.int<7> : !s32i
362+
// CIR: %[[CONST_8:.*]] = cir.const #cir.int<8> : !s32i
363+
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_6]], %[[CONST_7]], %[[CONST_8]] :
364+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
365+
// CIR: cir.store %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
366+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
367+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
368+
// CIR: %[[SHL:.*]] = cir.shift(left, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[TMP_B]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
369+
// CIR: cir.store %[[SHL]], %[[SHL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
370+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
371+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
372+
// CIR: %[[SHR:.*]] = cir.shift(right, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[TMP_B]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
373+
// CIR: cir.store %[[SHR]], %[[SHR_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
374+
375+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
376+
// LLVM: %[[VEC_B:.*]] = alloca <4 x i32>, i64 1, align 16
377+
// LLVM: %[[SHL_RES:.*]] = alloca <4 x i32>, i64 1, align 16
378+
// LLVM: %[[SHR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
379+
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
380+
// LLVM: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
381+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
382+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
383+
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[TMP_B]]
384+
// LLVM: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
385+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
386+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
387+
// LLVM: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]]
388+
// LLVM: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
389+
390+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
391+
// OGCG: %[[VEC_B:.*]] = alloca <4 x i32>, align 16
392+
// OGCG: %[[SHL_RES:.*]] = alloca <4 x i32>, align 16
393+
// OGCG: %[[SHR_RES:.*]] = alloca <4 x i32>, align 16
394+
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
395+
// OGCG: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
396+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
397+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
398+
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[TMP_B]]
399+
// OGCG: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
400+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
401+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
402+
// OGCG: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]]
403+
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16

clang/test/CIR/CodeGen/vector.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,68 @@ void foo7() {
324324
// OGCG: %[[TMP2:.*]] = load <4 x i32>, ptr %[[VEC]], align 16
325325
// OGCG: %[[NEW_VEC:.*]] = insertelement <4 x i32> %[[TMP2]], i32 %[[RES]], i32 2
326326
// OGCG: store <4 x i32> %[[NEW_VEC]], ptr %[[VEC]], align 16
327+
328+
void foo9() {
329+
vi4 a = {1, 2, 3, 4};
330+
vi4 b = {5, 6, 7, 8};
331+
332+
vi4 shl = a << b;
333+
vi4 shr = a >> b;
334+
}
335+
336+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init]
337+
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["b", init]
338+
// CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shl", init]
339+
// CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shr", init]
340+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
341+
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
342+
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
343+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
344+
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
345+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
346+
// CIR: cir.store %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
347+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
348+
// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i
349+
// CIR: %[[CONST_7:.*]] = cir.const #cir.int<7> : !s32i
350+
// CIR: %[[CONST_8:.*]] = cir.const #cir.int<8> : !s32i
351+
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_6]], %[[CONST_7]], %[[CONST_8]] :
352+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
353+
// CIR: cir.store %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
354+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
355+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
356+
// CIR: %[[SHL:.*]] = cir.shift(left, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[TMP_B]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
357+
// CIR: cir.store %[[SHL]], %[[SHL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
358+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
359+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
360+
// CIR: %[[SHR:.*]] = cir.shift(right, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[TMP_B]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
361+
// CIR: cir.store %[[SHR]], %[[SHR_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
362+
363+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
364+
// LLVM: %[[VEC_B:.*]] = alloca <4 x i32>, i64 1, align 16
365+
// LLVM: %[[SHL_RES:.*]] = alloca <4 x i32>, i64 1, align 16
366+
// LLVM: %[[SHR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
367+
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
368+
// LLVM: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
369+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
370+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
371+
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[TMP_B]]
372+
// LLVM: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
373+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
374+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
375+
// LLVM: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]]
376+
// LLVM: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
377+
378+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
379+
// OGCG: %[[VEC_B:.*]] = alloca <4 x i32>, align 16
380+
// OGCG: %[[SHL_RES:.*]] = alloca <4 x i32>, align 16
381+
// OGCG: %[[SHR_RES:.*]] = alloca <4 x i32>, align 16
382+
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
383+
// OGCG: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
384+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
385+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
386+
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[TMP_B]]
387+
// OGCG: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
388+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
389+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
390+
// OGCG: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]]
391+
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16

0 commit comments

Comments
 (0)