[llvm] [AArch64][GlobalISel] Lower unmerge to extract_subvector (PR #195046)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 30 02:40:55 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel
Author: David Green (davemgreen)
<details>
<summary>Changes</summary>
This follows and reuses the existing lowering for unmerge -> extract vector element, extending it to also lower unmerge -> subvector extract for half-sized vector extracts. This allows certain tablegen patterns to match.
An extra extract_subvector(dup) combine is needed to optimize away unnecessary instructions. The ext vs mov/dup brings us in-line with SDAG, but we may change both to use mov/dup.
---
Patch is 160.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/195046.diff
42 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64Combine.td (+15-2)
- (modified) llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp (+9)
- (modified) llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp (+16-3)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir (+6-3)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir (+7-6)
- (modified) llvm/test/CodeGen/AArch64/aarch64-dup-ext.ll (+1-1)
- (modified) llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll (+13-13)
- (modified) llvm/test/CodeGen/AArch64/aarch64-mulv.ll (+16-25)
- (modified) llvm/test/CodeGen/AArch64/aarch64-smull.ll (+15-15)
- (modified) llvm/test/CodeGen/AArch64/arm64-ext.ll (+3-3)
- (modified) llvm/test/CodeGen/AArch64/arm64-extract_subvector.ll (+20-42)
- (modified) llvm/test/CodeGen/AArch64/arm64-neon-2velem-high.ll (+36-36)
- (modified) llvm/test/CodeGen/AArch64/arm64-neon-2velem.ll (+65-65)
- (modified) llvm/test/CodeGen/AArch64/arm64-neon-3vdiff.ll (+1-1)
- (modified) llvm/test/CodeGen/AArch64/arm64-neon-add-pairwise.ll (+3-3)
- (modified) llvm/test/CodeGen/AArch64/arm64-neon-mul-div.ll (+4-4)
- (modified) llvm/test/CodeGen/AArch64/arm64-vabs.ll (+4-4)
- (modified) llvm/test/CodeGen/AArch64/arm64-vadd.ll (+1-1)
- (modified) llvm/test/CodeGen/AArch64/arm64-vhadd.ll (+11-19)
- (modified) llvm/test/CodeGen/AArch64/arm64-vmul.ll (+22-22)
- (modified) llvm/test/CodeGen/AArch64/arm64-vshift.ll (+6-6)
- (modified) llvm/test/CodeGen/AArch64/bitreverse.ll (+2-4)
- (modified) llvm/test/CodeGen/AArch64/bswap.ll (+1-2)
- (modified) llvm/test/CodeGen/AArch64/concat-vector.ll (+6-12)
- (modified) llvm/test/CodeGen/AArch64/double_reduct.ll (+31-31)
- (modified) llvm/test/CodeGen/AArch64/dup.ll (+8-16)
- (modified) llvm/test/CodeGen/AArch64/ext-narrow-index.ll (+10-20)
- (modified) llvm/test/CodeGen/AArch64/fptoi.ll (+4-8)
- (modified) llvm/test/CodeGen/AArch64/highextractbitcast.ll (+25-46)
- (modified) llvm/test/CodeGen/AArch64/neon-extadd.ll (+52-54)
- (modified) llvm/test/CodeGen/AArch64/neon-perm.ll (+4-10)
- (modified) llvm/test/CodeGen/AArch64/neon-shift-left-long.ll (+6-6)
- (modified) llvm/test/CodeGen/AArch64/phi.ll (+4-8)
- (modified) llvm/test/CodeGen/AArch64/reduce-and.ll (+6-6)
- (modified) llvm/test/CodeGen/AArch64/reduce-or.ll (+6-6)
- (modified) llvm/test/CodeGen/AArch64/reduce-xor.ll (+6-6)
- (modified) llvm/test/CodeGen/AArch64/rem-by-const.ll (+35-43)
- (modified) llvm/test/CodeGen/AArch64/rem.ll (+10-10)
- (modified) llvm/test/CodeGen/AArch64/shift.ll (+6-12)
- (modified) llvm/test/CodeGen/AArch64/st1-lane.ll (+42-90)
- (modified) llvm/test/CodeGen/AArch64/vec-combine-compare-to-bitmask.ll (+1-1)
- (modified) llvm/test/CodeGen/AArch64/vecreduce-fmul.ll (+22-22)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index fe953a627939d..5d26636fd3fb9 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -175,7 +175,7 @@ def form_duplane : GICombineRule <
>;
// Clean up G_UNMERGE(G_DUPLANE16) -> G_DUPLANE16
-class unmerge_duplane<Instruction Op> : GICombineRule <
+class unmerge_duplane<Instruction Op> : GICombineRule<
(defs root:$root),
(match (Op $a, $src, $c),
(G_UNMERGE_VALUES $d1, $d2, $a):$root,
@@ -186,8 +186,21 @@ def unmerge_duplane8 : unmerge_duplane<G_DUPLANE8>;
def unmerge_duplane16 : unmerge_duplane<G_DUPLANE16>;
def unmerge_duplane32 : unmerge_duplane<G_DUPLANE32>;
// G_DUPLANE64 is not included as the result in scalar.
+
+class extract_duplane<Instruction Op> : GICombineRule<
+ (defs root:$root),
+ (match (Op $a, $src, $c),
+ (G_EXTRACT_SUBVECTOR $d1, $a, $l):$root,
+ [{ return MRI.getType(${d1}.getReg()).getSizeInBits() == 64; }]),
+ (apply (Op $d1, $src, $c))
+>;
+def extract_duplane8 : extract_duplane<G_DUPLANE8>;
+def extract_duplane16 : extract_duplane<G_DUPLANE16>;
+def extract_duplane32 : extract_duplane<G_DUPLANE32>;
+
def unmerge_duplanes : GICombineGroup<[unmerge_duplane8, unmerge_duplane16,
- unmerge_duplane32]>;
+ unmerge_duplane32, extract_duplane8,
+ extract_duplane16, extract_duplane32]>;
def shuffle_vector_lowering : GICombineGroup<[dup, form_duplane, rev, ext, zip,
uzp, trn, fullrev, shuf_to_ins]>;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 21e6440d8957c..ae27b5b86c6a6 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -7862,6 +7862,15 @@ AArch64InstructionSelector::selectExtractHigh(MachineOperand &Root) const {
return {{[=](MachineInstrBuilder &MIB) { MIB.addUse(ExtReg); }}};
}
}
+ if (Extract->MI->getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR &&
+ Extract->MI->getNumOperands() == 3) {
+ LLT SrcTy = MRI.getType(Extract->MI->getOperand(1).getReg());
+ auto LaneIdx = Extract->MI->getOperand(2).getImm();
+ if (LaneIdx == SrcTy.getNumElements() / 2) {
+ Register ExtReg = Extract->MI->getOperand(1).getReg();
+ return {{[=](MachineInstrBuilder &MIB) { MIB.addUse(ExtReg); }}};
+ }
+ }
return std::nullopt;
}
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index 58aa2cc37c9b2..46fb14dbecf32 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -830,7 +830,9 @@ bool matchScalarizeVectorUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI) {
if (SrcTy.getSizeInBits() != 128 && SrcTy.getSizeInBits() != 64)
return false;
return SrcTy.isVector() && !SrcTy.isScalable() &&
- Unmerge.getNumOperands() == (unsigned)SrcTy.getNumElements() + 1;
+ (Unmerge.getNumOperands() == (unsigned)SrcTy.getNumElements() + 1 ||
+ (Unmerge.getNumDefs() == 2 && SrcTy.getSizeInBits() == 128 &&
+ MRI.getType(Unmerge.getReg(0)).getSizeInBits() == 64));
}
void applyScalarizeVectorUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
@@ -838,11 +840,22 @@ void applyScalarizeVectorUnmerge(MachineInstr &MI, MachineRegisterInfo &MRI,
auto &Unmerge = cast<GUnmerge>(MI);
Register Src1Reg = Unmerge.getReg(Unmerge.getNumOperands() - 1);
const LLT SrcTy = MRI.getType(Src1Reg);
+ const LLT DstTy = MRI.getType(Unmerge.getReg(0));
assert((SrcTy.isVector() && !SrcTy.isScalable()) &&
"Expected a fixed length vector");
- for (int I = 0; I < SrcTy.getNumElements(); ++I)
- B.buildExtractVectorElementConstant(Unmerge.getReg(I), Src1Reg, I);
+ if (DstTy.isVector()) {
+ assert(Unmerge.getNumDefs() == 2);
+ if (!MRI.use_empty(Unmerge.getReg(0)))
+ B.buildExtractSubvector(Unmerge.getReg(0), Src1Reg, 0);
+ if (!MRI.use_empty(Unmerge.getReg(1)))
+ B.buildExtractSubvector(Unmerge.getReg(1), Src1Reg,
+ SrcTy.getNumElements() / 2);
+ } else {
+ for (int I = 0; I < SrcTy.getNumElements(); ++I)
+ if (!MRI.use_empty(Unmerge.getReg(I)))
+ B.buildExtractVectorElementConstant(Unmerge.getReg(I), Src1Reg, I);
+ }
MI.eraseFromParent();
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir
index 0b533ff85fe86..1a9f8ed88ef4b 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-combiner-unmergedup.mir
@@ -10,8 +10,9 @@ body: |
; CHECK: [[COPY:%[0-9]+]]:_(<16 x s8>) = COPY $q0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; CHECK-NEXT: [[DUPLANE8_:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[DUPLANE8_1:%[0-9]+]]:_(<8 x s8>) = G_DUPLANE8 [[COPY]], [[C]](s64)
; CHECK-NEXT: $d0 = COPY [[DUPLANE8_]](<8 x s8>)
- ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_]](<8 x s8>)
+ ; CHECK-NEXT: $d1 = COPY [[DUPLANE8_1]](<8 x s8>)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%0:_(<16 x s8>) = COPY $q0
%1:_(s64) = G_CONSTANT i64 1
@@ -31,8 +32,9 @@ body: |
; CHECK: [[COPY:%[0-9]+]]:_(<8 x s16>) = COPY $q0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; CHECK-NEXT: [[DUPLANE16_:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[DUPLANE16_1:%[0-9]+]]:_(<4 x s16>) = G_DUPLANE16 [[COPY]], [[C]](s64)
; CHECK-NEXT: $d0 = COPY [[DUPLANE16_]](<4 x s16>)
- ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_]](<4 x s16>)
+ ; CHECK-NEXT: $d1 = COPY [[DUPLANE16_1]](<4 x s16>)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%0:_(<8 x s16>) = COPY $q0
%1:_(s64) = G_CONSTANT i64 1
@@ -52,8 +54,9 @@ body: |
; CHECK: [[COPY:%[0-9]+]]:_(<4 x s32>) = COPY $q0
; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
; CHECK-NEXT: [[DUPLANE32_:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64)
+ ; CHECK-NEXT: [[DUPLANE32_1:%[0-9]+]]:_(<2 x s32>) = G_DUPLANE32 [[COPY]], [[C]](s64)
; CHECK-NEXT: $d0 = COPY [[DUPLANE32_]](<2 x s32>)
- ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_]](<2 x s32>)
+ ; CHECK-NEXT: $d1 = COPY [[DUPLANE32_1]](<2 x s32>)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%0:_(<4 x s32>) = COPY $q0
%1:_(s64) = G_CONSTANT i64 1
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir
index 2452c3083cc86..52ef2d3578b33 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/postlegalizer-lowering-unmerge-ext.mir
@@ -11,7 +11,7 @@ body: |
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %v1:_(<4 x s32>) = COPY $q0
- ; CHECK-NEXT: %unused:_(<2 x s32>), %unmerge:_(<2 x s32>) = G_UNMERGE_VALUES %v1(<4 x s32>)
+ ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %v1(<4 x s32>), 2
; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>)
; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
@@ -34,7 +34,7 @@ body: |
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %v1:_(<8 x s16>) = COPY $q0
- ; CHECK-NEXT: %unused:_(<4 x s16>), %unmerge:_(<4 x s16>) = G_UNMERGE_VALUES %v1(<8 x s16>)
+ ; CHECK-NEXT: %unmerge:_(<4 x s16>) = G_EXTRACT_SUBVECTOR %v1(<8 x s16>), 4
; CHECK-NEXT: %fpext:_(<4 x s32>) = G_FPEXT %unmerge(<4 x s16>)
; CHECK-NEXT: $q0 = COPY %fpext(<4 x s32>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
@@ -57,7 +57,7 @@ body: |
; CHECK: liveins: $q0
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %v1:_(<16 x s8>) = COPY $q0
- ; CHECK-NEXT: %unused:_(<8 x s8>), %unmerge:_(<8 x s8>) = G_UNMERGE_VALUES %v1(<16 x s8>)
+ ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %v1(<16 x s8>), 8
; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>)
; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
@@ -83,7 +83,7 @@ body: |
; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF
; CHECK-NEXT: %C:_(s32) = COPY $w0
; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32)
- ; CHECK-NEXT: %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext(<16 x s8>)
+ ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0
; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>)
; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
@@ -109,7 +109,8 @@ body: |
; CHECK-NEXT: %implicit:_(<16 x s8>) = G_IMPLICIT_DEF
; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 8
; CHECK-NEXT: %ext:_(<16 x s8>) = G_EXT %v1, %implicit, %C(s32)
- ; CHECK-NEXT: %unmerge:_(<8 x s8>), %unused:_(<8 x s8>) = G_UNMERGE_VALUES %ext(<16 x s8>)
+ ; CHECK-NEXT: %unmerge:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 0
+ ; CHECK-NEXT: %unused:_(<8 x s8>) = G_EXTRACT_SUBVECTOR %ext(<16 x s8>), 8
; CHECK-NEXT: %fpext:_(<8 x s16>) = G_FPEXT %unmerge(<8 x s8>)
; CHECK-NEXT: %fpext2:_(<8 x s16>) = G_FPEXT %unused(<8 x s8>)
; CHECK-NEXT: $q0 = COPY %fpext(<8 x s16>)
@@ -139,7 +140,7 @@ body: |
; CHECK-NEXT: %implicit:_(<4 x s32>) = G_IMPLICIT_DEF
; CHECK-NEXT: %C:_(s32) = G_CONSTANT i32 9
; CHECK-NEXT: %ext:_(<4 x s32>) = G_EXT %v1, %implicit, %C(s32)
- ; CHECK-NEXT: %unmerge:_(<2 x s32>), %unused:_(<2 x s32>) = G_UNMERGE_VALUES %ext(<4 x s32>)
+ ; CHECK-NEXT: %unmerge:_(<2 x s32>) = G_EXTRACT_SUBVECTOR %ext(<4 x s32>), 0
; CHECK-NEXT: %fpext:_(<2 x s64>) = G_FPEXT %unmerge(<2 x s32>)
; CHECK-NEXT: $q0 = COPY %fpext(<2 x s64>)
; CHECK-NEXT: RET_ReallyLR implicit $q0
diff --git a/llvm/test/CodeGen/AArch64/aarch64-dup-ext.ll b/llvm/test/CodeGen/AArch64/aarch64-dup-ext.ll
index 9dfbe1a7f27e8..2334e0603ee43 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-dup-ext.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-dup-ext.ll
@@ -308,7 +308,7 @@ define <2 x i16> @dupsext_v2i8_v2i16(i8 %src, <2 x i8> %b) {
; CHECK-GI-NEXT: sbfx w8, w8, #8, #8
; CHECK-GI-NEXT: sshr v0.2s, v0.2s, #24
; CHECK-GI-NEXT: dup v1.4h, w8
-; CHECK-GI-NEXT: ushll v1.4s, v1.4h, #0
+; CHECK-GI-NEXT: zip1 v1.4h, v1.4h, v1.4h
; CHECK-GI-NEXT: mul v0.2s, v1.2s, v0.2s
; CHECK-GI-NEXT: ret
entry:
diff --git a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
index ea55c198a70f1..b6e9d248a2d26 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
@@ -321,8 +321,8 @@ define void @larger_smull(ptr nocapture noundef readonly %x, i16 noundef %y, ptr
; CHECK-GI-NEXT: mov x14, x11
; CHECK-GI-NEXT: subs x13, x13, #16
; CHECK-GI-NEXT: add x12, x12, #32
-; CHECK-GI-NEXT: mov d3, v1.d[1]
-; CHECK-GI-NEXT: mov d4, v2.d[1]
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
+; CHECK-GI-NEXT: ext v4.16b, v2.16b, v2.16b, #8
; CHECK-GI-NEXT: smull v1.4s, v0.4h, v1.4h
; CHECK-GI-NEXT: smull v2.4s, v0.4h, v2.4h
; CHECK-GI-NEXT: smull v3.4s, v0.4h, v3.4h
@@ -481,8 +481,8 @@ define void @larger_umull(ptr nocapture noundef readonly %x, i16 noundef %y, ptr
; CHECK-GI-NEXT: mov x13, x10
; CHECK-GI-NEXT: subs x12, x12, #16
; CHECK-GI-NEXT: add x11, x11, #32
-; CHECK-GI-NEXT: mov d3, v1.d[1]
-; CHECK-GI-NEXT: mov d4, v2.d[1]
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
+; CHECK-GI-NEXT: ext v4.16b, v2.16b, v2.16b, #8
; CHECK-GI-NEXT: xtn v0.4h, v0.4s
; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h
; CHECK-GI-NEXT: umull v3.4s, v0.4h, v3.4h
@@ -909,10 +909,10 @@ define i64 @red_mla_dup_ext_u8_s8_s64(ptr noalias noundef readonly captures(none
; CHECK-GI-NEXT: ushll2 v18.4s, v18.8h, #0
; CHECK-GI-NEXT: ushll v20.4s, v17.4h, #0
; CHECK-GI-NEXT: ushll2 v17.4s, v17.8h, #0
-; CHECK-GI-NEXT: mov d21, v19.d[1]
-; CHECK-GI-NEXT: mov d22, v18.d[1]
-; CHECK-GI-NEXT: mov d23, v20.d[1]
-; CHECK-GI-NEXT: mov d24, v17.d[1]
+; CHECK-GI-NEXT: ext v21.16b, v19.16b, v19.16b, #8
+; CHECK-GI-NEXT: ext v22.16b, v18.16b, v18.16b, #8
+; CHECK-GI-NEXT: ext v23.16b, v20.16b, v20.16b, #8
+; CHECK-GI-NEXT: ext v24.16b, v17.16b, v17.16b, #8
; CHECK-GI-NEXT: smlal v0.2d, v16.2s, v19.2s
; CHECK-GI-NEXT: smlal v2.2d, v16.2s, v18.2s
; CHECK-GI-NEXT: smlal v4.2d, v16.2s, v20.2s
@@ -1176,7 +1176,7 @@ define void @sink_v4i64_1(ptr %p, ptr %d, i64 %n, <2 x i32> %a) {
; CHECK-GI-NEXT: ldr q1, [x0]
; CHECK-GI-NEXT: subs x2, x2, #8
; CHECK-GI-NEXT: add x8, x8, #8
-; CHECK-GI-NEXT: mov d2, v1.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v1.16b, v1.16b, #8
; CHECK-GI-NEXT: smull v1.2d, v1.2s, v0.2s
; CHECK-GI-NEXT: smull v2.2d, v2.2s, v0.2s
; CHECK-GI-NEXT: shrn v1.2s, v1.2d, #15
@@ -1302,7 +1302,7 @@ define void @sink_v16s16_8(ptr %p, ptr %d, i64 %n, <16 x i8> %a) {
; CHECK-GI-NEXT: ldr q1, [x0]
; CHECK-GI-NEXT: subs x2, x2, #8
; CHECK-GI-NEXT: add x8, x8, #8
-; CHECK-GI-NEXT: mov d2, v1.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v1.16b, v1.16b, #8
; CHECK-GI-NEXT: smull v1.8h, v1.8b, v0.8b
; CHECK-GI-NEXT: smull v2.8h, v2.8b, v0.8b
; CHECK-GI-NEXT: cmlt v1.8h, v1.8h, #0
@@ -1460,8 +1460,8 @@ define void @matrix_mul_unsigned_and_double(i32 %N, ptr nocapture %C, ptr nocapt
; CHECK-GI-NEXT: ldur q2, [x9, #8]
; CHECK-GI-NEXT: add x9, x1, w0, uxtw #2
; CHECK-GI-NEXT: add w0, w0, #16
-; CHECK-GI-NEXT: mov d3, v1.d[1]
-; CHECK-GI-NEXT: mov d4, v2.d[1]
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
+; CHECK-GI-NEXT: ext v4.16b, v2.16b, v2.16b, #8
; CHECK-GI-NEXT: umull v1.4s, v0.4h, v1.4h
; CHECK-GI-NEXT: umull v2.4s, v0.4h, v2.4h
; CHECK-GI-NEXT: umull v3.4s, v0.4h, v3.4h
@@ -1731,7 +1731,7 @@ define noundef <8 x i16> @cmplx_mul_combined_re_im(<8 x i16> noundef %a, i64 %sc
; CHECK-GI-NEXT: sqneg v2.8h, v1.8h
; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI15_0]
; CHECK-GI-NEXT: tbl v1.16b, { v2.16b, v3.16b }, v1.16b
-; CHECK-GI-NEXT: mov d2, v0.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: dup v3.8h, w0
; CHECK-GI-NEXT: sqdmull v2.4s, v2.4h, v3.4h
; CHECK-GI-NEXT: sqdmull v5.4s, v4.4h, v1.4h
diff --git a/llvm/test/CodeGen/AArch64/aarch64-mulv.ll b/llvm/test/CodeGen/AArch64/aarch64-mulv.ll
index fecc6554667fa..27cf4a116bda6 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-mulv.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-mulv.ll
@@ -146,7 +146,7 @@ define i8 @mulv_v16i8(<16 x i8> %a) {
;
; CHECK-GI-LABEL: mulv_v16i8:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d1, v0.d[1]
+; CHECK-GI-NEXT: ext v1.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: mul v0.8b, v0.8b, v1.8b
; CHECK-GI-NEXT: umov w8, v0.b[0]
; CHECK-GI-NEXT: umov w9, v0.b[1]
@@ -194,8 +194,8 @@ define i8 @mulv_v32i8(<32 x i8> %a) {
;
; CHECK-GI-LABEL: mulv_v32i8:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d2, v0.d[1]
-; CHECK-GI-NEXT: mov d3, v1.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
; CHECK-GI-NEXT: mul v0.8b, v0.8b, v2.8b
; CHECK-GI-NEXT: mul v1.8b, v1.8b, v3.8b
; CHECK-GI-NEXT: mul v0.8b, v0.8b, v1.8b
@@ -303,7 +303,7 @@ define i16 @mulv_v8i16(<8 x i16> %a) {
;
; CHECK-GI-LABEL: mulv_v8i16:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d1, v0.d[1]
+; CHECK-GI-NEXT: ext v1.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: mul v0.4h, v0.4h, v1.4h
; CHECK-GI-NEXT: umov w8, v0.h[0]
; CHECK-GI-NEXT: umov w9, v0.h[1]
@@ -335,8 +335,8 @@ define i16 @mulv_v16i16(<16 x i16> %a) {
;
; CHECK-GI-LABEL: mulv_v16i16:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d2, v0.d[1]
-; CHECK-GI-NEXT: mov d3, v1.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
; CHECK-GI-NEXT: mul v0.4h, v0.4h, v2.4h
; CHECK-GI-NEXT: mul v1.4h, v1.4h, v3.4h
; CHECK-GI-NEXT: mul v0.4h, v0.4h, v1.4h
@@ -384,23 +384,14 @@ entry:
}
define i32 @mulv_v4i32(<4 x i32> %a) {
-; CHECK-SD-LABEL: mulv_v4i32:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8
-; CHECK-SD-NEXT: mul v0.2s, v0.2s, v1.2s
-; CHECK-SD-NEXT: mov w8, v0.s[1]
-; CHECK-SD-NEXT: fmov w9, s0
-; CHECK-SD-NEXT: mul w0, w9, w8
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: mulv_v4i32:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d1, v0.d[1]
-; CHECK-GI-NEXT: mul v0.2s, v0.2s, v1.2s
-; CHECK-GI-NEXT: mov w8, v0.s[1]
-; CHECK-GI-NEXT: fmov w9, s0
-; CHECK-GI-NEXT: mul w0, w9, w8
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: mulv_v4i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: mul v0.2s, v0.2s, v1.2s
+; CHECK-NEXT: mov w8, v0.s[1]
+; CHECK-NEXT: fmov w9, s0
+; CHECK-NEXT: mul w0, w9, w8
+; CHECK-NEXT: ret
entry:
%arg1 = call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %a)
ret i32 %arg1
@@ -419,8 +410,8 @@ define i32 @mulv_v8i32(<8 x i32> %a) {
;
; CHECK-GI-LABEL: mulv_v8i32:
; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov d2, v0.d[1]
-; CHECK-GI-NEXT: mov d3, v1.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
+; CHECK-GI-NEXT: ext v3.16b, v1.16b, v1.16b, #8
; CHECK-GI-NEXT: mul v0.2s, v0.2s, v2.2s
; CHECK-GI-NEXT: mul v1.2s, v1.2s, v3.2s
; CHECK-GI-NEXT: mul v0.2s, v0.2s, v1.2s
diff --git a/llvm/test/CodeGen/AArch64/aarch64-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
index 5896b408be49c..ee5b2e00c6a69 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-smull.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-smull.ll
@@ -1726,7 +1726,7 @@ define <8 x i32> @umull_and_v8i32(<8 x i16> %src1, <8 x i32> %src2) {
; CHECK-GI-NEXT: movi v3.2d, #0x0000ff000000ff
; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b
; CHECK-GI-NEXT: and v2.16b, v2.16b, v3.16b
-; CHECK-GI-NEXT: mov d3, v0.d[1]
+; CHECK-GI-NEXT: ext v3.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
; CHECK-GI-NEXT: xtn v2.4h, v2.4s
; CHECK-GI-NEXT: umull v0.4s, v0.4h, v1.4h
@@ -1759,7 +1759,7 @@ define <8 x i32> @umull_and_v8i32_dup(<8 x i16> %src1, i32 %src2) {
; CHECK-GI-LABEL: umull_and_v8i32_dup:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: and w8, w0, #0xff
-; CHECK-GI-NEXT: mov d2, v0.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: dup v1.4s, w8
; CHECK-GI-NEXT: xtn v1.4h, v1.4s
; CHECK-GI-NEXT: umull v0.4s, v0.4h, v1.4h
@@ -1832,7 +1832,7 @@ define <4 x i64> @umull_and_v4i64(<4 x i32> %src1, <4 x i64> %src2) {
; CHECK-GI-NEXT: movi v3.2d, #0x000000000000ff
; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b
; CHECK-GI-NEXT: and v2.16b, v2.16b, v3.16b
-; CHECK-GI-NEXT: mov d3, v0.d[1]
+; CHECK-GI-NEXT: ext v3.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: xtn v1.2s, v1.2d
; CHECK-GI-NEXT: xtn v2.2s, v2.2d
; CHECK-GI-NEXT: umull v0.2d, v0.2s, v1.2s
@@ -1865,7 +1865,7 @@ define <4 x i64> @umull_and_v4i64_dup(<4 x i32> %src1, i64 %src2) {
; CHECK-GI-LABEL: umull_and_v4i64_dup:
; CHECK-GI: // %bb.0: // %entry
; CHECK-GI-NEXT: and x8, x0, #0xff
-; CHECK-GI-NEXT: mov d2, v0.d[1]
+; CHECK-GI-NEXT: ext v2.16b, v0.16b, v0.16b, #8
; CHECK-GI-NEXT: dup v1.2d, x8
; CHECK-GI-NEXT: xtn v1.2s, v1.2d
; CHECK-GI-NEXT: umull v0.2d, v0.2s, v1.2s
@@ -1902,7 +1902,7 @@ define void @pmlsl2_v8i16_uzp1(<16 x i8> %0, <8 x i16> %1, ptr %2, ptr %3) {
; CHECK-GI-LABEL: pmlsl2_v8i16_uzp1:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: ldr q2, [x1, #16]
-; CHECK-GI-NEXT: mov d0, v0.d[1]
+; CHECK...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/195046
More information about the llvm-commits
mailing list