Skip to content

Commit 02f6743

Browse files
committed
[CIR] Implement folder for VecSplatOp
1 parent 621a7d0 commit 02f6743

File tree

6 files changed

+112
-45
lines changed

6 files changed

+112
-45
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,6 +2307,8 @@ def VecSplatOp : CIR_Op<"vec.splat", [Pure,
23072307
let assemblyFormat = [{
23082308
$value `:` type($value) `,` qualified(type($result)) attr-dict
23092309
}];
2310+
2311+
let hasFolder = 1;
23102312
}
23112313

23122314
//===----------------------------------------------------------------------===//

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,18 @@ LogicalResult cir::VecTernaryOp::verify() {
16971697
return success();
16981698
}
16991699

1700+
// VecSplatOp
1701+
OpFoldResult cir::VecSplatOp::fold(FoldAdaptor adaptor) {
1702+
mlir::Attribute value = adaptor.getValue();
1703+
if (!mlir::isa_and_nonnull<cir::IntAttr>(value) &&
1704+
!mlir::isa_and_nonnull<cir::FPAttr>(value))
1705+
return {};
1706+
1707+
SmallVector<mlir::Attribute, 16> elements(getType().getSize(), value);
1708+
return cir::ConstVectorAttr::get(
1709+
getType(), mlir::ArrayAttr::get(getContext(), elements));
1710+
}
1711+
17001712
OpFoldResult cir::VecTernaryOp::fold(FoldAdaptor adaptor) {
17011713
mlir::Attribute cond = adaptor.getCond();
17021714
mlir::Attribute lhs = adaptor.getLhs();

clang/lib/CIR/Dialect/Transforms/CIRCanonicalize.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ void CIRCanonicalizePass::runOnOperation() {
142142
// Many operations are here to perform a manual `fold` in
143143
// applyOpPatternsGreedily.
144144
if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
145-
VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecTernaryOp>(op))
145+
VecExtractOp, VecShuffleOp, VecShuffleDynamicOp, VecSplatOp,
146+
VecTernaryOp>(op))
146147
ops.push_back(op);
147148
});
148149

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

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,65 +1095,83 @@ void foo17() {
10951095

10961096
void foo18() {
10971097
vi4 a = {1, 2, 3, 4};
1098-
vi4 shl = a << 3;
1098+
int sv = 3;
1099+
vi4 shl = a << sv;
10991100

11001101
uvi4 b = {1u, 2u, 3u, 4u};
1101-
uvi4 shr = b >> 3u;
1102+
unsigned int usv = 3u;
1103+
uvi4 shr = b >> usv;
11021104
}
11031105

11041106
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init]
1107+
// CIR: %[[SV:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["sv", init]
11051108
// CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shl", init]
11061109
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>, ["b", init]
1110+
// CIR: %[[USV:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["usv", init]
11071111
// CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>, ["shr", init]
1108-
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
1109-
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
1110-
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
1111-
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
1112-
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
1113-
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
1112+
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
11141113
// CIR: cir.store{{.*}} %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
1114+
// CIR: %[[SV_VAL:.*]] = cir.const #cir.int<3> : !s32i
1115+
// CIR: cir.store{{.*}} %[[SV_VAL]], %[[SV]] : !s32i, !cir.ptr<!s32i>
11151116
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
1116-
// CIR: %[[SH_AMOUNT:.*]] = cir.const #cir.int<3> : !s32i
1117-
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[SH_AMOUNT]] : !s32i, !cir.vector<4 x !s32i>
1117+
// CIR: %[[TMP_SV:.*]] = cir.load{{.*}} %[[SV]] : !cir.ptr<!s32i>, !s32i
1118+
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[TMP_SV]] : !s32i, !cir.vector<4 x !s32i>
11181119
// CIR: %[[SHL:.*]] = cir.shift(left, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[SPLAT_VEC]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
11191120
// CIR: cir.store{{.*}} %[[SHL]], %[[SHL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
1120-
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u32i
1121-
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !u32i
1122-
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !u32i
1123-
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u32i
1124-
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
1125-
// CIR-SAME: !u32i, !u32i, !u32i, !u32i) : !cir.vector<4 x !u32i>
1121+
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !u32i, !u32i, !u32i, !u32i) : !cir.vector<4 x !u32i>
11261122
// CIR: cir.store{{.*}} %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>
1123+
// CIR: %[[USV_VAL:.*]] = cir.const #cir.int<3> : !u32i
1124+
// CIR: cir.store{{.*}} %[[USV_VAL]], %[[USV]] : !u32i, !cir.ptr<!u32i>
11271125
// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !u32i>>, !cir.vector<4 x !u32i>
1128-
// CIR: %[[SH_AMOUNT:.*]] = cir.const #cir.int<3> : !u32i
1129-
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[SH_AMOUNT]] : !u32i, !cir.vector<4 x !u32i>
1126+
// CIR: %[[TMP_USV:.*]] = cir.load{{.*}} %[[USV]] : !cir.ptr<!u32i>, !u32i
1127+
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[TMP_USV]] : !u32i, !cir.vector<4 x !u32i>
11301128
// CIR: %[[SHR:.*]] = cir.shift(right, %[[TMP_B]] : !cir.vector<4 x !u32i>, %[[SPLAT_VEC]] : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
11311129
// CIR: cir.store{{.*}} %[[SHR]], %[[SHR_RES]] : !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>
11321130

11331131
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
1132+
// LLVM: %[[SV:.*]] = alloca i32, i64 1, align 4
11341133
// LLVM: %[[SHL_RES:.*]] = alloca <4 x i32>, i64 1, align 16
11351134
// LLVM: %[[VEC_B:.*]] = alloca <4 x i32>, i64 1, align 16
1135+
// LLVM: %[[USV:.*]] = alloca i32, i64 1, align 4
11361136
// LLVM: %[[SHR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
11371137
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
1138+
// LLVM: store i32 3, ptr %[[SV]], align 4
11381139
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
1139-
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], splat (i32 3)
1140+
// LLVM: %[[TMP_SV:.*]] = load i32, ptr %[[SV]], align 4
1141+
// LLVM: %[[SI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_SV]], i64 0
1142+
// LLVM: %[[S_VEC:.*]] = shufflevector <4 x i32> %[[SI]], <4 x i32> poison, <4 x i32> zeroinitializer
1143+
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[S_VEC]]
11401144
// LLVM: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
11411145
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_B]], align 16
1146+
// LLVM: store i32 3, ptr %[[USV]], align 4
11421147
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
1143-
// LLVM: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], splat (i32 3)
1148+
// LLVM: %[[TMP_USV:.*]] = load i32, ptr %[[USV]], align 4
1149+
// LLVM: %[[USI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_USV]], i64 0
1150+
// LLVM: %[[US_VEC:.*]] = shufflevector <4 x i32> %[[USI]], <4 x i32> poison, <4 x i32> zeroinitializer
1151+
// LLVM: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], %[[US_VEC]]
11441152
// LLVM: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
11451153

11461154
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
1155+
// OGCG: %[[SV:.*]] = alloca i32, align 4
11471156
// OGCG: %[[SHL_RES:.*]] = alloca <4 x i32>, align 16
11481157
// OGCG: %[[VEC_B:.*]] = alloca <4 x i32>, align 16
1158+
// OGCG: %[[USV:.*]] = alloca i32, align 4
11491159
// OGCG: %[[SHR_RES:.*]] = alloca <4 x i32>, align 16
11501160
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
1161+
// OGCG: store i32 3, ptr %[[SV]], align 4
11511162
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
1152-
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], splat (i32 3)
1163+
// OGCG: %[[TMP_SV:.*]] = load i32, ptr %[[SV]], align 4
1164+
// OGCG: %[[SI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_SV]], i64 0
1165+
// OGCG: %[[S_VEC:.*]] = shufflevector <4 x i32> %[[SI]], <4 x i32> poison, <4 x i32> zeroinitializer
1166+
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[S_VEC]]
11531167
// OGCG: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
11541168
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_B]], align 16
1169+
// OGCG: store i32 3, ptr %[[USV]], align 4
11551170
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
1156-
// OGCG: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], splat (i32 3)
1171+
// OGCG: %[[TMP_USV:.*]] = load i32, ptr %[[USV]], align 4
1172+
// OGCG: %[[USI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_USV]], i64 0
1173+
// OGCG: %[[US_VEC:.*]] = shufflevector <4 x i32> %[[USI]], <4 x i32> poison, <4 x i32> zeroinitializer
1174+
// OGCG: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], %[[US_VEC]]
11571175
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
11581176

11591177
void foo19() {

clang/test/CIR/CodeGen/vector.cpp

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,65 +1073,83 @@ void foo17() {
10731073

10741074
void foo18() {
10751075
vi4 a = {1, 2, 3, 4};
1076-
vi4 shl = a << 3;
1076+
int sv = 3;
1077+
vi4 shl = a << sv;
10771078

10781079
uvi4 b = {1u, 2u, 3u, 4u};
1079-
uvi4 shr = b >> 3u;
1080+
unsigned int usv = 3u;
1081+
uvi4 shr = b >> usv;
10801082
}
10811083

10821084
// CIR: %[[VEC_A:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init]
1085+
// CIR: %[[SV:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["sv", init]
10831086
// CIR: %[[SHL_RES:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["shl", init]
10841087
// CIR: %[[VEC_B:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>, ["b", init]
1088+
// CIR: %[[USV:.*]] = cir.alloca !u32i, !cir.ptr<!u32i>, ["usv", init]
10851089
// CIR: %[[SHR_RES:.*]] = cir.alloca !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>, ["shr", init]
1086-
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
1087-
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i
1088-
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i
1089-
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i
1090-
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
1091-
// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
1090+
// CIR: %[[VEC_A_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i>
10921091
// CIR: cir.store{{.*}} %[[VEC_A_VAL]], %[[VEC_A]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
1092+
// CIR: %[[SV_VAL:.*]] = cir.const #cir.int<3> : !s32i
1093+
// CIR: cir.store{{.*}} %[[SV_VAL]], %[[SV]] : !s32i, !cir.ptr<!s32i>
10931094
// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[VEC_A]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
1094-
// CIR: %[[SH_AMOUNT:.*]] = cir.const #cir.int<3> : !s32i
1095-
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[SH_AMOUNT]] : !s32i, !cir.vector<4 x !s32i>
1095+
// CIR: %[[TMP_SV:.*]] = cir.load{{.*}} %[[SV]] : !cir.ptr<!s32i>, !s32i
1096+
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[TMP_SV]] : !s32i, !cir.vector<4 x !s32i>
10961097
// CIR: %[[SHL:.*]] = cir.shift(left, %[[TMP_A]] : !cir.vector<4 x !s32i>, %[[SPLAT_VEC]] : !cir.vector<4 x !s32i>) -> !cir.vector<4 x !s32i>
10971098
// CIR: cir.store{{.*}} %[[SHL]], %[[SHL_RES]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>
1098-
// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u32i
1099-
// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !u32i
1100-
// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !u32i
1101-
// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u32i
1102-
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] :
1103-
// CIR-SAME: !u32i, !u32i, !u32i, !u32i) : !cir.vector<4 x !u32i>
1099+
// CIR: %[[VEC_B_VAL:.*]] = cir.vec.create({{.*}}, {{.*}}, {{.*}}, {{.*}} : !u32i, !u32i, !u32i, !u32i) : !cir.vector<4 x !u32i>
11041100
// CIR: cir.store{{.*}} %[[VEC_B_VAL]], %[[VEC_B]] : !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>
1101+
// CIR: %[[USV_VAL:.*]] = cir.const #cir.int<3> : !u32i
1102+
// CIR: cir.store{{.*}} %[[USV_VAL]], %[[USV]] : !u32i, !cir.ptr<!u32i>
11051103
// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[VEC_B]] : !cir.ptr<!cir.vector<4 x !u32i>>, !cir.vector<4 x !u32i>
1106-
// CIR: %[[SH_AMOUNT:.*]] = cir.const #cir.int<3> : !u32i
1107-
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[SH_AMOUNT]] : !u32i, !cir.vector<4 x !u32i>
1104+
// CIR: %[[TMP_USV:.*]] = cir.load{{.*}} %[[USV]] : !cir.ptr<!u32i>, !u32i
1105+
// CIR: %[[SPLAT_VEC:.*]] = cir.vec.splat %[[TMP_USV]] : !u32i, !cir.vector<4 x !u32i>
11081106
// CIR: %[[SHR:.*]] = cir.shift(right, %[[TMP_B]] : !cir.vector<4 x !u32i>, %[[SPLAT_VEC]] : !cir.vector<4 x !u32i>) -> !cir.vector<4 x !u32i>
11091107
// CIR: cir.store{{.*}} %[[SHR]], %[[SHR_RES]] : !cir.vector<4 x !u32i>, !cir.ptr<!cir.vector<4 x !u32i>>
11101108

11111109
// LLVM: %[[VEC_A:.*]] = alloca <4 x i32>, i64 1, align 16
1110+
// LLVM: %[[SV:.*]] = alloca i32, i64 1, align 4
11121111
// LLVM: %[[SHL_RES:.*]] = alloca <4 x i32>, i64 1, align 16
11131112
// LLVM: %[[VEC_B:.*]] = alloca <4 x i32>, i64 1, align 16
1113+
// LLVM: %[[USV:.*]] = alloca i32, i64 1, align 4
11141114
// LLVM: %[[SHR_RES:.*]] = alloca <4 x i32>, i64 1, align 16
11151115
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
1116+
// LLVM: store i32 3, ptr %[[SV]], align 4
11161117
// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
1117-
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], splat (i32 3)
1118+
// LLVM: %[[TMP_SV:.*]] = load i32, ptr %[[SV]], align 4
1119+
// LLVM: %[[SI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_SV]], i64 0
1120+
// LLVM: %[[S_VEC:.*]] = shufflevector <4 x i32> %[[SI]], <4 x i32> poison, <4 x i32> zeroinitializer
1121+
// LLVM: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[S_VEC]]
11181122
// LLVM: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
11191123
// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_B]], align 16
1124+
// LLVM: store i32 3, ptr %[[USV]], align 4
11201125
// LLVM: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
1121-
// LLVM: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], splat (i32 3)
1126+
// LLVM: %[[TMP_USV:.*]] = load i32, ptr %[[USV]], align 4
1127+
// LLVM: %[[USI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_USV]], i64 0
1128+
// LLVM: %[[US_VEC:.*]] = shufflevector <4 x i32> %[[USI]], <4 x i32> poison, <4 x i32> zeroinitializer
1129+
// LLVM: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], %[[US_VEC]]
11221130
// LLVM: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
11231131

11241132
// OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16
1133+
// OGCG: %[[SV:.*]] = alloca i32, align 4
11251134
// OGCG: %[[SHL_RES:.*]] = alloca <4 x i32>, align 16
11261135
// OGCG: %[[VEC_B:.*]] = alloca <4 x i32>, align 16
1136+
// OGCG: %[[USV:.*]] = alloca i32, align 4
11271137
// OGCG: %[[SHR_RES:.*]] = alloca <4 x i32>, align 16
11281138
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_A]], align 16
1139+
// OGCG: store i32 3, ptr %[[SV]], align 4
11291140
// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[VEC_A]], align 16
1130-
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], splat (i32 3)
1141+
// OGCG: %[[TMP_SV:.*]] = load i32, ptr %[[SV]], align 4
1142+
// OGCG: %[[SI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_SV]], i64 0
1143+
// OGCG: %[[S_VEC:.*]] = shufflevector <4 x i32> %[[SI]], <4 x i32> poison, <4 x i32> zeroinitializer
1144+
// OGCG: %[[SHL:.*]] = shl <4 x i32> %[[TMP_A]], %[[S_VEC]]
11311145
// OGCG: store <4 x i32> %[[SHL]], ptr %[[SHL_RES]], align 16
11321146
// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC_B]], align 16
1147+
// OGCG: store i32 3, ptr %[[USV]], align 4
11331148
// OGCG: %[[TMP_B:.*]] = load <4 x i32>, ptr %[[VEC_B]], align 16
1134-
// OGCG: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], splat (i32 3)
1149+
// OGCG: %[[TMP_USV:.*]] = load i32, ptr %[[USV]], align 4
1150+
// OGCG: %[[USI:.*]] = insertelement <4 x i32> poison, i32 %[[TMP_USV]], i64 0
1151+
// OGCG: %[[US_VEC:.*]] = shufflevector <4 x i32> %[[USI]], <4 x i32> poison, <4 x i32> zeroinitializer
1152+
// OGCG: %[[SHR:.*]] = lshr <4 x i32> %[[TMP_B]], %[[US_VEC]]
11351153
// OGCG: store <4 x i32> %[[SHR]], ptr %[[SHR_RES]], align 16
11361154

11371155
void foo19() {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: cir-opt %s -cir-canonicalize -o - | FileCheck %s
2+
3+
!s32i = !cir.int<s, 32>
4+
5+
module {
6+
cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> {
7+
%v = cir.const #cir.int<3> : !s32i
8+
%vec = cir.vec.splat %v : !s32i, !cir.vector<4 x !s32i>
9+
cir.return %vec : !cir.vector<4 x !s32i>
10+
}
11+
12+
// CHECK: cir.func @fold_shuffle_vector_op_test() -> !cir.vector<4 x !s32i> {
13+
// CHECK-NEXT: %0 = cir.const #cir.const_vector<[#cir.int<3> : !s32i, #cir.int<3> : !s32i,
14+
// CHECK-SAME: #cir.int<3> : !s32i, #cir.int<3> : !s32i]> : !cir.vector<4 x !s32i>
15+
// CHECK-NEXT: cir.return %0 : !cir.vector<4 x !s32i>
16+
}

0 commit comments

Comments
 (0)