Skip to content

Commit ab09038

Browse files
committed
[CIR][LLVMLowering] Upstream binary operators for VectorType
1 parent 63a4cae commit ab09038

File tree

3 files changed

+330
-12
lines changed

3 files changed

+330
-12
lines changed

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,19 +1189,15 @@ mlir::LogicalResult CIRToLLVMBinOpLowering::matchAndRewrite(
11891189
return op.emitError() << "inconsistent operands' types not supported yet";
11901190

11911191
mlir::Type type = op.getRhs().getType();
1192-
assert(!cir::MissingFeatures::vectorType());
11931192
if (!mlir::isa<cir::IntType, cir::BoolType, cir::CIRFPTypeInterface,
1194-
mlir::IntegerType>(type))
1193+
mlir::IntegerType, cir::VectorType>(type))
11951194
return op.emitError() << "operand type not supported yet";
11961195

1197-
auto llvmTy = getTypeConverter()->convertType(op.getType());
1198-
mlir::Type llvmEltTy =
1199-
mlir::isa<mlir::VectorType>(llvmTy)
1200-
? mlir::cast<mlir::VectorType>(llvmTy).getElementType()
1201-
: llvmTy;
1202-
auto rhs = adaptor.getRhs();
1203-
auto lhs = adaptor.getLhs();
1196+
const mlir::Type llvmTy = getTypeConverter()->convertType(op.getType());
1197+
const mlir::Type llvmEltTy = elementTypeIfVector(llvmTy);
12041198

1199+
const mlir::Value rhs = adaptor.getRhs();
1200+
const mlir::Value lhs = adaptor.getLhs();
12051201
type = elementTypeIfVector(type);
12061202

12071203
switch (op.getKind()) {
@@ -1285,7 +1281,6 @@ mlir::LogicalResult CIRToLLVMBinOpLowering::matchAndRewrite(
12851281
}
12861282
break;
12871283
}
1288-
12891284
return mlir::LogicalResult::success();
12901285
}
12911286

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

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,165 @@ void foo9() {
400400
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
401401
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
402402
// OGCG: %[[SHR:.*]] = ashr <4 x i32> %[[TMP_A]], %[[TMP_B]]
403-
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
403+
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
404+
405+
void foo11() {
406+
vi4 a = {1, 2, 3, 4};
407+
vi4 b = {5, 6, 7, 8};
408+
409+
vi4 c = a + b;
410+
vi4 d = a - b;
411+
vi4 e = a * b;
412+
vi4 f = a / b;
413+
vi4 g = a % b;
414+
vi4 h = a & b;
415+
vi4 i = a | b;
416+
vi4 j = a ^ b;
417+
}
418+
419+
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init]
420+
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["b", init]
421+
// CIR: %[[ADD_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["c", init]
422+
// CIR: %[[SUB_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["d", init]
423+
// CIR: %[[MUL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["e", init]
424+
// CIR: %[[DIV_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["f", init]
425+
// CIR: %[[REM_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["g", init]
426+
// CIR: %[[AND_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["h", init]
427+
// CIR: %[[OR_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["i", init]
428+
// CIR: %[[XOR_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["j", init]
429+
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
430+
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
431+
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
432+
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
433+
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
434+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
435+
// CIR: cir.store %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
436+
// CIR: %[[CONST_5:.*]] = cir.const #cir.int<5> : !s32i
437+
// CIR: %[[CONST_6:.*]] = cir.const #cir.int<6> : !s32i
438+
// CIR: %[[CONST_7:.*]] = cir.const #cir.int<7> : !s32i
439+
// CIR: %[[CONST_8:.*]] = cir.const #cir.int<8> : !s32i
440+
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_5]], %[[CONST_6]], %[[CONST_7]], %[[CONST_8]] :
441+
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
442+
// CIR: cir.store %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
443+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
444+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
445+
// CIR: %[[ADD:.*]] = cir.binop(add, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
446+
// CIR: cir.store %[[ADD]], %[[ADD_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
447+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
448+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
449+
// CIR: %[[SUB:.*]] = cir.binop(sub, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
450+
// CIR: cir.store %[[SUB]], %[[SUB_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
451+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
452+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
453+
// CIR: %[[MUL:.*]] = cir.binop(mul, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
454+
// CIR: cir.store %[[MUL]], %[[MUL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
455+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
456+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
457+
// CIR: %[[DIV:.*]] = cir.binop(div, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
458+
// CIR: cir.store %[[DIV]], %[[DIV_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
459+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
460+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
461+
// CIR: %[[REM:.*]] = cir.binop(rem, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
462+
// CIR: cir.store %[[REM]], %[[REM_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
463+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
464+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
465+
// CIR: %[[AND:.*]] = cir.binop(and, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
466+
// CIR: cir.store %[[AND]], %[[AND_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
467+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
468+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
469+
// CIR: %[[OR:.*]] = cir.binop(or, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
470+
// CIR: cir.store %[[OR]], %[[OR_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
471+
// CIR: %[[TMP_A:.*]] = cir.load %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
472+
// CIR: %[[TMP_B:.*]] = cir.load %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
473+
// CIR: %[[XOR:.*]] = cir.binop(xor, %[[TMP_A]], %[[TMP_B]]) : !cir.vector<4 x !s32i>
474+
// CIR: cir.store %[[XOR]], %[[XOR_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
475+
476+
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
477+
// LLVM: %[[VEC_B:.*]] = alloca <4 x i32>, i64 1, align 16
478+
// LLVM: %[[ADD_RES:.*]] = alloca <4 x i32>, i64 1, align 16
479+
// LLVM: %[[SUB_RES:.*]] = alloca <4 x i32>, i64 1, align 16
480+
// LLVM: %[[MUL_RES:.*]] = alloca <4 x i32>, i64 1, align 16
481+
// LLVM: %[[DIV_RES:.*]] = alloca <4 x i32>, i64 1, align 16
482+
// LLVM: %[[REM_RES:.*]] = alloca <4 x i32>, i64 1, align 16
483+
// LLVM: %[[AND_RES:.*]] = alloca <4 x i32>, i64 1, align 16
484+
// LLVM: %[[OR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
485+
// LLVM: %[[XOR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
486+
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
487+
// LLVM: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
488+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
489+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
490+
// LLVM: %[[ADD:.*]] = add <4 x i32> %[[TMP_A]], %[[TMP_B]]
491+
// LLVM: store <4 x i32> %[[ADD]], ptr %[[ADD_RES]], align 16
492+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
493+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
494+
// LLVM: %[[SUB:.*]] = sub <4 x i32> %[[TMP_A]], %[[TMP_B]]
495+
// LLVM: store <4 x i32> %[[SUB]], ptr %[[SUB_RES]], align 16
496+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
497+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
498+
// LLVM: %[[MUL:.*]] = mul <4 x i32> %[[TMP_A]], %[[TMP_B]]
499+
// LLVM: store <4 x i32> %[[MUL]], ptr %[[MUL_RES]], align 16
500+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
501+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
502+
// LLVM: %[[DIV:.*]] = sdiv <4 x i32> %[[TMP_A]], %[[TMP_B]]
503+
// LLVM: store <4 x i32> %[[DIV]], ptr %[[DIV_RES]], align 16
504+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
505+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
506+
// LLVM: %[[REM:.*]] = srem <4 x i32> %[[TMP_A]], %[[TMP_B]]
507+
// LLVM: store <4 x i32> %[[REM]], ptr %[[REM_RES]], align 16
508+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
509+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
510+
// LLVM: %[[AND:.*]] = and <4 x i32> %[[TMP_A]], %[[TMP_B]]
511+
// LLVM: store <4 x i32> %[[AND]], ptr %[[AND_RES]], align 16
512+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
513+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
514+
// LLVM: %[[OR:.*]] = or <4 x i32> %[[TMP_A]], %[[TMP_B]]
515+
// LLVM: store <4 x i32> %[[OR]], ptr %[[OR_RES]], align 16
516+
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
517+
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
518+
// LLVM: %[[XOR:.*]] = xor <4 x i32> %[[TMP_A]], %[[TMP_B]]
519+
// LLVM: store <4 x i32> %[[XOR]], ptr %[[XOR_RES]], align 16
520+
521+
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
522+
// OGCG: %[[VEC_B:.*]] = alloca <4 x i32>, align 16
523+
// OGCG: %[[ADD_RES:.*]] = alloca <4 x i32>, align 16
524+
// OGCG: %[[SUB_RES:.*]] = alloca <4 x i32>, align 16
525+
// OGCG: %[[MUL_RES:.*]] = alloca <4 x i32>, align 16
526+
// OGCG: %[[DIV_RES:.*]] = alloca <4 x i32>, align 16
527+
// OGCG: %[[REM_RES:.*]] = alloca <4 x i32>, align 16
528+
// OGCG: %[[AND_RES:.*]] = alloca <4 x i32>, align 16
529+
// OGCG: %[[OR_RES:.*]] = alloca <4 x i32>, align 16
530+
// OGCG: %[[XOR_RES:.*]] = alloca <4 x i32>, align 16
531+
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
532+
// OGCG: store <4 x i32> <i32 5, i32 6, i32 7, i32 8>, ptr %[[VEC_B]], align 16
533+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
534+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
535+
// OGCG: %[[ADD:.*]] = add <4 x i32> %[[TMP_A]], %[[TMP_B]]
536+
// OGCG: store <4 x i32> %[[ADD]], ptr %[[ADD_RES]], align 16
537+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
538+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
539+
// OGCG: %[[SUB:.*]] = sub <4 x i32> %[[TMP_A]], %[[TMP_B]]
540+
// OGCG: store <4 x i32> %[[SUB]], ptr %[[SUB_RES]], align 16
541+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
542+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
543+
// OGCG: %[[MUL:.*]] = mul <4 x i32> %[[TMP_A]], %[[TMP_B]]
544+
// OGCG: store <4 x i32> %[[MUL]], ptr %[[MUL_RES]], align 16
545+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
546+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
547+
// OGCG: %[[DIV:.*]] = sdiv <4 x i32> %[[TMP_A]], %[[TMP_B]]
548+
// OGCG: store <4 x i32> %[[DIV]], ptr %[[DIV_RES]], align 16
549+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
550+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
551+
// OGCG: %[[REM:.*]] = srem <4 x i32> %[[TMP_A]], %[[TMP_B]]
552+
// OGCG: store <4 x i32> %[[REM]], ptr %[[REM_RES]], align 16
553+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
554+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
555+
// OGCG: %[[AND:.*]] = and <4 x i32> %[[TMP_A]], %[[TMP_B]]
556+
// OGCG: store <4 x i32> %[[AND]], ptr %[[AND_RES]], align 16
557+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
558+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
559+
// OGCG: %[[OR:.*]] = or <4 x i32> %[[TMP_A]], %[[TMP_B]]
560+
// OGCG: store <4 x i32> %[[OR]], ptr %[[OR_RES]], align 16
561+
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
562+
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
563+
// OGCG: %[[XOR:.*]] = xor <4 x i32> %[[TMP_A]], %[[TMP_B]]
564+
// OGCG: store <4 x i32> %[[XOR]], ptr %[[XOR_RES]], align 16

0 commit comments

Comments
 (0)