define <4 x i8> @vadd_vx_v4i8_commute(<4 x i8> %va, i8 %b, <4 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vadd_vx_v4i8_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e8, mf4, ta, mu
-; CHECK-NEXT: vadd.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vadd.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <4 x i8> poison, i8 %b, i32 0
%vb = shufflevector <4 x i8> %elt.head, <4 x i8> poison, <4 x i32> zeroinitializer
define <2 x i8> @vand_vx_v2i8_commute(<2 x i8> %va, i8 %b, <2 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vand_vx_v2i8_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e8, mf8, ta, mu
-; CHECK-NEXT: vand.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vand.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <2 x i8> poison, i8 %b, i32 0
%vb = shufflevector <2 x i8> %elt.head, <2 x i8> poison, <2 x i32> zeroinitializer
define <2 x float> @vfadd_vf_v2f32_commute(<2 x float> %va, float %b, <2 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vfadd_vf_v2f32_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, mu
-; CHECK-NEXT: vfmv.v.f v9, fa0
; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, mu
-; CHECK-NEXT: vfadd.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vfadd.vf v8, v8, fa0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <2 x float> poison, float %b, i32 0
%vb = shufflevector <2 x float> %elt.head, <2 x float> poison, <2 x i32> zeroinitializer
define <8 x i16> @vmul_vx_v8i16_commute(<8 x i16> %va, i16 %b, <8 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vmul_vx_v8i16_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 8, e16, m1, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e16, m1, ta, mu
-; CHECK-NEXT: vmul.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vmul.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <8 x i16> poison, i16 %b, i32 0
%vb = shufflevector <8 x i16> %elt.head, <8 x i16> poison, <8 x i32> zeroinitializer
define <4 x i8> @vor_vx_v4i8_commute(<4 x i8> %va, i8 %b, <4 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vor_vx_v4i8_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 4, e8, mf4, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e8, mf4, ta, mu
-; CHECK-NEXT: vor.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vor.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <4 x i8> poison, i8 %b, i32 0
%vb = shufflevector <4 x i8> %elt.head, <4 x i8> poison, <4 x i32> zeroinitializer
define <2 x i8> @vxor_vx_v2i8_commute(<2 x i8> %va, i8 %b, <2 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vxor_vx_v2i8_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetivli zero, 2, e8, mf8, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e8, mf8, ta, mu
-; CHECK-NEXT: vxor.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vxor.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <2 x i8> poison, i8 %b, i32 0
%vb = shufflevector <2 x i8> %elt.head, <2 x i8> poison, <2 x i32> zeroinitializer
define <vscale x 1 x i8> @vadd_vx_nxv1i8_commute(<vscale x 1 x i8> %va, i8 %b, <vscale x 1 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vadd_vx_nxv1i8_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a2, zero, e8, mf8, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e8, mf8, ta, mu
-; CHECK-NEXT: vadd.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vadd.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <vscale x 1 x i8> poison, i8 %b, i32 0
%vb = shufflevector <vscale x 1 x i8> %elt.head, <vscale x 1 x i8> poison, <vscale x 1 x i32> zeroinitializer
define <vscale x 32 x i16> @vand_vx_nxv32i16_commute(<vscale x 32 x i16> %va, i16 %b, <vscale x 32 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vand_vx_nxv32i16_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a2, zero, e16, m8, ta, mu
-; CHECK-NEXT: vmv.v.x v16, a0
; CHECK-NEXT: vsetvli zero, a1, e16, m8, ta, mu
-; CHECK-NEXT: vand.vv v8, v16, v8, v0.t
+; CHECK-NEXT: vand.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <vscale x 32 x i16> poison, i16 %b, i32 0
%vb = shufflevector <vscale x 32 x i16> %elt.head, <vscale x 32 x i16> poison, <vscale x 32 x i32> zeroinitializer
define <vscale x 16 x i32> @vmul_vx_nxv16i32_commute(<vscale x 16 x i32> %va, i32 %b, <vscale x 16 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vmul_vx_nxv16i32_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a2, zero, e32, m8, ta, mu
-; CHECK-NEXT: vmv.v.x v16, a0
; CHECK-NEXT: vsetvli zero, a1, e32, m8, ta, mu
-; CHECK-NEXT: vmul.vv v8, v16, v8, v0.t
+; CHECK-NEXT: vmul.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <vscale x 16 x i32> poison, i32 %b, i32 0
%vb = shufflevector <vscale x 16 x i32> %elt.head, <vscale x 16 x i32> poison, <vscale x 16 x i32> zeroinitializer
define <vscale x 2 x i32> @vor_vx_nxv2i32_commute(<vscale x 2 x i32> %va, i32 %b, <vscale x 2 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vor_vx_nxv2i32_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu
-; CHECK-NEXT: vor.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vor.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <vscale x 2 x i32> poison, i32 %b, i32 0
%vb = shufflevector <vscale x 2 x i32> %elt.head, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer
define <vscale x 1 x i16> @vxor_vx_nxv1i16_commute(<vscale x 1 x i16> %va, i16 %b, <vscale x 1 x i1> %m, i32 zeroext %evl) {
; CHECK-LABEL: vxor_vx_nxv1i16_commute:
; CHECK: # %bb.0:
-; CHECK-NEXT: vsetvli a2, zero, e16, mf4, ta, mu
-; CHECK-NEXT: vmv.v.x v9, a0
; CHECK-NEXT: vsetvli zero, a1, e16, mf4, ta, mu
-; CHECK-NEXT: vxor.vv v8, v9, v8, v0.t
+; CHECK-NEXT: vxor.vx v8, v8, a0, v0.t
; CHECK-NEXT: ret
%elt.head = insertelement <vscale x 1 x i16> poison, i16 %b, i32 0
%vb = shufflevector <vscale x 1 x i16> %elt.head, <vscale x 1 x i16> poison, <vscale x 1 x i32> zeroinitializer
// If this node is commutative, consider the commuted order.
bool isCommIntrinsic = N->isCommutativeIntrinsic(CDP);
if (NodeInfo.hasProperty(SDNPCommutative) || isCommIntrinsic) {
- assert((N->getNumChildren()>=2 || isCommIntrinsic) &&
+ unsigned Skip = isCommIntrinsic ? 1 : 0; // First operand is intrinsic id.
+ assert(N->getNumChildren() >= (2 + Skip) &&
"Commutative but doesn't have 2 children!");
- // Don't count children which are actually register references.
- unsigned NC = 0;
- for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i) {
+ // Don't allow commuting children which are actually register references.
+ bool NoRegisters = true;
+ unsigned i = 0 + Skip;
+ unsigned e = 2 + Skip;
+ for (; i != e; ++i) {
TreePatternNode *Child = N->getChild(i);
if (Child->isLeaf())
if (DefInit *DI = dyn_cast<DefInit>(Child->getLeafValue())) {
Record *RR = DI->getDef();
if (RR->isSubClassOf("Register"))
- continue;
+ NoRegisters = false;
}
- NC++;
}
// Consider the commuted order.
- if (isCommIntrinsic) {
- // Commutative intrinsic. First operand is the intrinsic id, 2nd and 3rd
- // operands are the commutative operands, and there might be more operands
- // after those.
- assert(NC >= 3 &&
- "Commutative intrinsic should have at least 3 children!");
- std::vector<std::vector<TreePatternNodePtr>> Variants;
- Variants.push_back(std::move(ChildVariants[0])); // Intrinsic id.
- Variants.push_back(std::move(ChildVariants[2]));
- Variants.push_back(std::move(ChildVariants[1]));
- for (unsigned i = 3; i != NC; ++i)
- Variants.push_back(std::move(ChildVariants[i]));
- CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
- } else if (NC == N->getNumChildren()) {
+ if (NoRegisters) {
std::vector<std::vector<TreePatternNodePtr>> Variants;
- Variants.push_back(std::move(ChildVariants[1]));
- Variants.push_back(std::move(ChildVariants[0]));
- for (unsigned i = 2; i != NC; ++i)
+ unsigned i = 0;
+ if (isCommIntrinsic)
+ Variants.push_back(std::move(ChildVariants[i++])); // Intrinsic id.
+ Variants.push_back(std::move(ChildVariants[i + 1]));
+ Variants.push_back(std::move(ChildVariants[i]));
+ i += 2;
+ // Remaining operands are not commuted.
+ for (; i != N->getNumChildren(); ++i)
Variants.push_back(std::move(ChildVariants[i]));
CombineChildVariants(N, Variants, OutVariants, CDP, DepVars);
}