[llvm] [GlobalIsel] Transform build_vector(binop(_, C), ...) -> binop(bv, constant bv) (PR #73577)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 14:28:17 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
@llvm/pr-subscribers-backend-aarch64
Author: Thorsten Schütt (tschuett)
<details>
<summary>Changes</summary>
test plan: ninja check-llvm-codegen
Port of https://github.com/llvm/llvm-project/pull/67358
The almost duplicated code is caused by the distinction of integers and floats.
Transforms a build vector of identically binops where the RHS is always a constant into a binop of two build vectors. The second is a constant build vector. Instead of O(n) binops, we take one vector binop and gain one constant build vector. The constant build vector might trigger other combines.
Differences: constants are not immediates but G_CONSTANT resp. G_FCONSTANT. Thus the hit rate may be higher, e.g., the constant might be hidden behind a COPY.
Credits: @<!-- -->preames
---
Patch is 279.10 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73577.diff
18 Files Affected:
- (modified) llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h (+3)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h (+54)
- (modified) llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h (+5)
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+7-1)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+85)
- (modified) llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp (+11)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/combine-build-vector-to-binop.mir (+236)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/inline-memset.mir (+87-79)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/sdiv.i32.ll (+90-180)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/sdiv.i64.ll (+478-942)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/srem.i32.ll (+82-164)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/srem.i64.ll (+470-926)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/urem.i32.ll (+31-62)
- (modified) llvm/test/CodeGen/AMDGPU/GlobalISel/urem.i64.ll (+230-398)
- (modified) llvm/test/CodeGen/AMDGPU/llvm.log.ll (+214-129)
- (modified) llvm/test/CodeGen/AMDGPU/llvm.log10.ll (+214-129)
- (modified) llvm/test/CodeGen/AMDGPU/v_pack.ll (+3-3)
- (modified) llvm/test/CodeGen/AMDGPU/v_sat_pk_u8_i16.ll (+40-33)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index ba72a3b71ffd70b..1eb9f5816bdb036 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -812,6 +812,9 @@ class CombinerHelper {
// Given a binop \p MI, commute operands 1 and 2.
void applyCommuteBinOpOperands(MachineInstr &MI);
+ /// Transform build_vector (binop(_, C), ...) -> binop(bv, constant bv)
+ bool matchBuildVectorToBinOp(MachineInstr &MI, BuildFnTy &MatchInfo);
+
private:
/// Checks for legality of an indexed variant of \p LdSt.
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 6ab1d4550c51ca9..26742496327e912 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -558,6 +558,60 @@ class GVecReduce : public GenericMachineInstr {
}
};
+// Represents an integer binary operation.
+class GIBinOp : public GenericMachineInstr {
+public:
+ Register getLHSReg() const { return getReg(1); }
+ Register getRHSReg() const { return getReg(2); }
+
+ static bool classof(const MachineInstr *MI) {
+ switch (MI->getOpcode()) {
+ case TargetOpcode::G_ADD:
+ case TargetOpcode::G_SUB:
+ case TargetOpcode::G_MUL:
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_UDIV:
+ case TargetOpcode::G_SREM:
+ case TargetOpcode::G_UREM:
+ case TargetOpcode::G_AND:
+ case TargetOpcode::G_OR:
+ case TargetOpcode::G_XOR:
+ case TargetOpcode::G_SMIN:
+ case TargetOpcode::G_SMAX:
+ case TargetOpcode::G_UMIN:
+ case TargetOpcode::G_UMAX:
+ return true;
+ default:
+ return false;
+ }
+ };
+};
+
+// Represents a floating point binary operation.
+class GFBinOp : public GenericMachineInstr {
+public:
+ Register getLHSReg() const { return getReg(1); }
+ Register getRHSReg() const { return getReg(2); }
+
+ static bool classof(const MachineInstr *MI) {
+ switch (MI->getOpcode()) {
+ case TargetOpcode::G_FMINNUM:
+ case TargetOpcode::G_FMAXNUM:
+ case TargetOpcode::G_FMINNUM_IEEE:
+ case TargetOpcode::G_FMAXNUM_IEEE:
+ case TargetOpcode::G_FMINIMUM:
+ case TargetOpcode::G_FMAXIMUM:
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV:
+ case TargetOpcode::G_FPOW:
+ return true;
+ default:
+ return false;
+ }
+ };
+};
} // namespace llvm
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index e0101a5ac1ca804..94da5f5e0d14b21 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -1061,6 +1061,11 @@ class MachineIRBuilder {
MachineInstrBuilder buildBuildVectorConstant(const DstOp &Res,
ArrayRef<APInt> Ops);
+ /// Build and insert \p Res = G_BUILD_VECTOR \p Op0, ... where each OpN is
+ /// built with G_FCONSTANT.
+ MachineInstrBuilder buildBuildVectorConstant(const DstOp &Res,
+ ArrayRef<APFloat> Ops);
+
/// Build and insert \p Res = G_BUILD_VECTOR with \p Src replicated to fill
/// the number of elements
MachineInstrBuilder buildSplatVector(const DstOp &Res,
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 9a84ab80157f35f..a56327ff49696b5 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1236,6 +1236,12 @@ def select_to_minmax: GICombineRule<
[{ return Helper.matchSimplifySelectToMinMax(*${root}, ${info}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${info}); }])>;
+def build_vector_to_binop : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_BUILD_VECTOR):$root,
+ [{ return Helper.matchBuildVectorToBinOp(*${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
@@ -1309,7 +1315,7 @@ def all_combines : GICombineGroup<[trivial_combines, insert_vec_elt_combines,
intdiv_combines, mulh_combines, redundant_neg_operands,
and_or_disjoint_mask, fma_combines, fold_binop_into_select,
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
- fsub_to_fneg, commute_constant_to_rhs]>;
+ fsub_to_fneg, commute_constant_to_rhs, build_vector_to_binop]>;
// A combine group used to for prelegalizer combiners at -O0. The combines in
// this group have been selected based on experiments to balance code size and
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index c2a7c2d01188129..a0b2e86c6148cff 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6224,3 +6224,88 @@ void CombinerHelper::applyCommuteBinOpOperands(MachineInstr &MI) {
MI.getOperand(2).setReg(LHSReg);
Observer.changedInstr(MI);
}
+
+// Transform build_vector of binop(_,C) -> binop(BV, constant BV).
+bool CombinerHelper::matchBuildVectorToBinOp(MachineInstr &MI,
+ BuildFnTy &MatchInfo) {
+ GBuildVector *BuildVector = cast<GBuildVector>(&MI);
+ Register Dst = BuildVector->getReg(0);
+
+ unsigned NumOfSources = BuildVector->getNumSources();
+ if (NumOfSources == 1)
+ return false;
+
+ LLT ElementTy = MRI.getType(BuildVector->getSourceReg(0));
+ LLT BVTy = MRI.getType(BuildVector->getReg(0));
+
+ MachineInstr *FirstDef = MRI.getVRegDef(BuildVector->getSourceReg(0));
+ const unsigned Opcode = FirstDef->getOpcode();
+ SmallVector<Register> LHS;
+
+ if (isa<GIBinOp>(FirstDef)) {
+ SmallVector<APInt> RHS;
+
+ // Collect registers and constants and check for non-conformance.
+ for (unsigned I = 0; I < NumOfSources; ++I) {
+ // Check for integer binop of the same kind.
+ GIBinOp *BinOp = getOpcodeDef<GIBinOp>(BuildVector->getSourceReg(I), MRI);
+ if (!BinOp || BinOp->getOpcode() != Opcode)
+ return false;
+ // Check for constant on rhs.
+ auto IConstant =
+ getIConstantVRegValWithLookThrough(BinOp->getRHSReg(), MRI);
+ if (!IConstant)
+ return false;
+ LHS.push_back(BinOp->getLHSReg());
+ RHS.push_back(IConstant->Value);
+ }
+
+ if (!isLegalOrBeforeLegalizer({Opcode, {BVTy, ElementTy}}))
+ return false;
+
+ // Binop of build_vector, integer constant build_vector.
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.setInstrAndDebugLoc(*BuildVector);
+ Register First = MRI.createGenericVirtualRegister(BVTy);
+ Register Second = MRI.createGenericVirtualRegister(BVTy);
+ B.buildBuildVector(First, LHS);
+ B.buildBuildVectorConstant(Second, RHS);
+ B.buildInstr(Opcode, {Dst}, {First, Second}); // DEBUG: did not happen
+ };
+ return true;
+ } else if (isa<GFBinOp>(FirstDef)) {
+ SmallVector<APFloat> RHS;
+
+ // Collect registers and constants and check for non-conformance.
+ for (unsigned I = 0; I < NumOfSources; ++I) {
+ // Check for float binop of the same kind.
+ GFBinOp *BinOp = getOpcodeDef<GFBinOp>(BuildVector->getSourceReg(I), MRI);
+ if (!BinOp || BinOp->getOpcode() != Opcode)
+ return false;
+ // Check for float constant on rhs.
+ auto FConstant =
+ getFConstantVRegValWithLookThrough(BinOp->getRHSReg(), MRI);
+ if (!FConstant)
+ return false;
+ LHS.push_back(BinOp->getLHSReg());
+ RHS.push_back(FConstant->Value);
+ }
+
+ if (!isLegalOrBeforeLegalizer({Opcode, {BVTy, ElementTy}}))
+ return false;
+
+ // Binop of build_vector, floating point constant build_vector.
+ MatchInfo = [=](MachineIRBuilder &B) {
+ B.setInstrAndDebugLoc(*BuildVector);
+ Register First = MRI.createGenericVirtualRegister(BVTy);
+ Register Second = MRI.createGenericVirtualRegister(BVTy);
+ B.buildBuildVector(First, LHS);
+ B.buildBuildVectorConstant(Second, RHS);
+ B.buildInstr(Opcode, {Dst}, {First, Second});
+ };
+ return true;
+ } else {
+ // Not a binop.
+ return false;
+ }
+}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 80e9c08e850b683..89d5d73a2394a39 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -700,6 +700,17 @@ MachineIRBuilder::buildBuildVectorConstant(const DstOp &Res,
return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
}
+MachineInstrBuilder
+MachineIRBuilder::buildBuildVectorConstant(const DstOp &Res,
+ ArrayRef<APFloat> Ops) {
+ SmallVector<SrcOp> TmpVec;
+ TmpVec.reserve(Ops.size());
+ LLT EltTy = Res.getLLTTy(*getMRI()).getElementType();
+ for (const auto &Op : Ops)
+ TmpVec.push_back(buildFConstant(EltTy, Op));
+ return buildInstr(TargetOpcode::G_BUILD_VECTOR, Res, TmpVec);
+}
+
MachineInstrBuilder MachineIRBuilder::buildSplatVector(const DstOp &Res,
const SrcOp &Src) {
SmallVector<SrcOp, 8> TmpVec(Res.getLLTTy(*getMRI()).getNumElements(), Src);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-build-vector-to-binop.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-build-vector-to-binop.mir
new file mode 100644
index 000000000000000..ea69bd4a9be2d5f
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-build-vector-to-binop.mir
@@ -0,0 +1,236 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -o - -mtriple=aarch64 -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s
+
+---
+name: build_vector_success_add
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_success_add
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C1]](s32)
+ ; CHECK-NEXT: %bv:_(<2 x s32>) = G_ADD [[BUILD_VECTOR]], [[BUILD_VECTOR1]]
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), [[COPY1]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = G_CONSTANT i32 10
+ %3:_(s32) = G_CONSTANT i32 1
+ %4:_(s32) = G_ADD %0, %2
+ %5:_(s32) = G_ADD %1, %3
+ %bv:_(<2 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %0(s32)
+ %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %1(s32)
+ $w0 = COPY %extract(s32)
+ $w1 = COPY %extract2(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: build_vector_failure_mixed
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_failure_mixed
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
+ ; CHECK-NEXT: [[ADD:%[0-9]+]]:_(s32) = G_ADD [[COPY]], [[C]]
+ ; CHECK-NEXT: [[SUB:%[0-9]+]]:_(s32) = G_SUB [[COPY1]], [[C1]]
+ ; CHECK-NEXT: %bv:_(<2 x s32>) = G_BUILD_VECTOR [[ADD]](s32), [[SUB]](s32)
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), [[COPY1]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = G_CONSTANT i32 5
+ %3:_(s32) = G_CONSTANT i32 11
+ %4:_(s32) = G_ADD %0, %2
+ %5:_(s32) = G_SUB %1, %3
+ %bv:_(<2 x s32>) = G_BUILD_VECTOR %4(s32), %5(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %0(s32)
+ %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<2 x s32>), %1(s32)
+ $w0 = COPY %extract(s32)
+ $w1 = COPY %extract2(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: build_vector_success_sub
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_success_sub
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w3
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
+ ; CHECK-NEXT: %bv:_(<4 x s32>) = G_SUB [[BUILD_VECTOR]], [[BUILD_VECTOR1]]
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY3]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = COPY $w2
+ %3:_(s32) = COPY $w3
+ %4:_(s32) = G_CONSTANT i32 10
+ %5:_(s32) = G_CONSTANT i32 1
+ %6:_(s32) = G_CONSTANT i32 2
+ %7:_(s32) = G_CONSTANT i32 3
+ %8:_(s32) = G_SUB %0, %4
+ %9:_(s32) = G_SUB %1, %5
+ %10:_(s32) = G_SUB %2, %6
+ %11:_(s32) = G_SUB %3, %7
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %8(s32), %9(s32), %10(s32), %11(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %3(s32)
+ %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %0(s32)
+ $w0 = COPY %extract(s32)
+ $w1 = COPY %extract2(s32)
+ RET_ReallyLR implicit $w0
+
+
+...
+---
+name: build_vector_success_fadd
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_success_fadd
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w3
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+01
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.100000e+01
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.200000e+01
+ ; CHECK-NEXT: [[C3:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.400000e+01
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY1]](s32), [[COPY2]](s32), [[COPY3]](s32)
+ ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
+ ; CHECK-NEXT: %bv:_(<4 x s32>) = G_FADD [[BUILD_VECTOR]], [[BUILD_VECTOR1]]
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY3]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = COPY $w2
+ %3:_(s32) = COPY $w3
+ %4:_(s32) = G_FCONSTANT float 10.000000e+00
+ %5:_(s32) = G_FCONSTANT float 11.000000e+00
+ %6:_(s32) = G_FCONSTANT float 12.000000e+00
+ %7:_(s32) = G_FCONSTANT float 14.000000e+00
+ %8:_(s32) = G_FADD %0, %4
+ %9:_(s32) = G_FADD %1, %5
+ %10:_(s32) = G_FADD %2, %6
+ %11:_(s32) = G_FADD %3, %7
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %8(s32), %9(s32), %10(s32), %11(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %3(s32)
+ %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %0(s32)
+ $w0 = COPY %extract(s32)
+ $w1 = COPY %extract2(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: build_vector_failed_no_constant_for_you
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_failed_no_constant_for_you
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w3
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.000000e+01
+ ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.100000e+01
+ ; CHECK-NEXT: [[C2:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.200000e+01
+ ; CHECK-NEXT: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[COPY]], [[C]]
+ ; CHECK-NEXT: [[FADD1:%[0-9]+]]:_(s32) = G_FADD [[COPY1]], [[C1]]
+ ; CHECK-NEXT: [[FADD2:%[0-9]+]]:_(s32) = G_FADD [[COPY2]], [[C2]]
+ ; CHECK-NEXT: [[FADD3:%[0-9]+]]:_(s32) = G_FADD [[COPY3]], [[COPY]]
+ ; CHECK-NEXT: %bv:_(<4 x s32>) = G_BUILD_VECTOR [[FADD]](s32), [[FADD1]](s32), [[FADD2]](s32), [[FADD3]](s32)
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY3]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = COPY $w2
+ %3:_(s32) = COPY $w3
+ %4:_(s32) = G_FCONSTANT float 10.000000e+00
+ %5:_(s32) = G_FCONSTANT float 11.000000e+00
+ %6:_(s32) = G_FCONSTANT float 12.000000e+00
+ %8:_(s32) = G_FADD %0, %4
+ %9:_(s32) = G_FADD %1, %5
+ %10:_(s32) = G_FADD %2, %6
+ %11:_(s32) = G_FADD %3, %0
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %8(s32), %9(s32), %10(s32), %11(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %3(s32)
+ %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %0(s32)
+ $w0 = COPY %extract(s32)
+ $w1 = COPY %extract2(s32)
+ RET_ReallyLR implicit $w0
+
+...
+---
+name: build_vector_failed_no_binop
+liveins:
+body: |
+ bb.0:
+
+ ; CHECK-LABEL: name: build_vector_failed_no_binop
+ ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $w1
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY $w2
+ ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY $w3
+ ; CHECK-NEXT: [[FNEG:%[0-9]+]]:_(s32) = G_FNEG [[COPY]]
+ ; CHECK-NEXT: [[FNEG1:%[0-9]+]]:_(s32) = G_FNEG [[COPY1]]
+ ; CHECK-NEXT: [[FNEG2:%[0-9]+]]:_(s32) = G_FNEG [[COPY2]]
+ ; CHECK-NEXT: [[FNEG3:%[0-9]+]]:_(s32) = G_FNEG [[COPY3]]
+ ; CHECK-NEXT: %bv:_(<4 x s32>) = G_BUILD_VECTOR [[FNEG]](s32), [[FNEG1]](s32), [[FNEG2]](s32), [[FNEG3]](s32)
+ ; CHECK-NEXT: %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY3]](s32)
+ ; CHECK-NEXT: %extract2:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), [[COPY]](s32)
+ ; CHECK-NEXT: $w0 = COPY %extract(s32)
+ ; CHECK-NEXT: $w1 = COPY %extract2(s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $w0
+ %0:_(s32) = COPY $w0
+ %1:_(s32) = COPY $w1
+ %2:_(s32) = COPY $w2
+ %3:_(s32) = COPY $w3
+ %8:_(s32) = G_FNEG %0
+ %9:_(s32) = G_FNEG %1
+ %10:_(s32) = G_FNEG %2
+ %11:_(s32) = G_FNEG %3
+ %bv:_(<4 x s32>) = G_BUILD_VECTOR %8(s32), %9(s32), %10(s32), %11(s32)
+ %extract:_(s32) = G_EXTRACT_VECTOR_ELT %bv(<4 x s32>), %3(s32)
+ ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/73577
More information about the llvm-commits
mailing list