[llvm] [GlobalISel][AArch64] Allow vector ptr to int unmerges (PR #115228)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 14:32:50 PST 2024
https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/115228
Vector pointer -> scalar integer unmerges are already legal. This loosens the verifier check for vector-of-pointers -> vectors.
>From cb34bb28e8af526cfb45e04467d6468605003585 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 6 Nov 2024 22:31:17 +0000
Subject: [PATCH] [GlobalISel][AArch64] Allow vector ptr to int unmerges
Vector pointer -> scalar integer unmerges are already legal. This loosens the
verifier check for vector-of-pointers -> vectors.
---
llvm/lib/CodeGen/MachineVerifier.cpp | 4 +-
llvm/test/CodeGen/AArch64/getelementptr.ll | 478 ++++++++++++++++++
.../MachineVerifier/test_g_unmerge_values.mir | 5 +
3 files changed, 486 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AArch64/getelementptr.ll
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index e2c09fe25d55cd..10369928f7a05b 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1487,7 +1487,9 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
LLT SrcTy = MRI->getType(MI->getOperand(NumDsts).getReg());
if (DstTy.isVector()) {
// This case is the converse of G_CONCAT_VECTORS.
- if (!SrcTy.isVector() || SrcTy.getScalarType() != DstTy.getScalarType() ||
+ if (!SrcTy.isVector() ||
+ (SrcTy.getScalarType() != DstTy.getScalarType() &&
+ !SrcTy.isPointerVector()) ||
SrcTy.isScalableVector() != DstTy.isScalableVector() ||
SrcTy.getSizeInBits() != NumDsts * DstTy.getSizeInBits())
report("G_UNMERGE_VALUES source operand does not match vector "
diff --git a/llvm/test/CodeGen/AArch64/getelementptr.ll b/llvm/test/CodeGen/AArch64/getelementptr.ll
new file mode 100644
index 00000000000000..91a98dfa91aca6
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/getelementptr.ll
@@ -0,0 +1,478 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=aarch64 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
+; RUN: llc -mtriple=aarch64 -global-isel -global-isel-abort=2 -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-GI
+
+define ptr @s(ptr %p, i32 %q) {
+; CHECK-LABEL: s:
+; CHECK: // %bb.0:
+; CHECK-NEXT: add x0, x0, w1, sxtw #2
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, i32 %q
+ ret ptr %d
+}
+
+define <2 x ptr> @v2(<2 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v2:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: dup v1.2s, w0
+; CHECK-SD-NEXT: sshll v1.2d, v1.2s, #2
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: dup v1.2s, w0
+; CHECK-GI-NEXT: adrp x8, .LCPI1_0
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI1_0]
+; CHECK-GI-NEXT: fmov x9, d2
+; CHECK-GI-NEXT: mov x11, v2.d[1]
+; CHECK-GI-NEXT: sshll v1.2d, v1.2s, #0
+; CHECK-GI-NEXT: fmov x8, d1
+; CHECK-GI-NEXT: mov x10, v1.d[1]
+; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: mul x9, x10, x11
+; CHECK-GI-NEXT: mov v1.d[0], x8
+; CHECK-GI-NEXT: mov v1.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <2 x ptr> %p, i32 %q
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3(<3 x ptr> %p, i32 %q) {
+; CHECK-LABEL: v3:
+; CHECK: // %bb.0:
+; CHECK-NEXT: dup v3.2s, w0
+; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-NEXT: mov w8, #2 // =0x2
+; CHECK-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-NEXT: sshll v1.2d, v3.2s, #2
+; CHECK-NEXT: fmov s3, w0
+; CHECK-NEXT: sshll v3.2d, v3.2s, #0
+; CHECK-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-NEXT: fmov d1, x8
+; CHECK-NEXT: ushl d3, d3, d1
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: add d2, d2, d3
+; CHECK-NEXT: ret
+ %d = getelementptr i32, <3 x ptr> %p, i32 %q
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4(<4 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v4:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: dup v2.2s, w0
+; CHECK-SD-NEXT: sshll v2.2d, v2.2s, #2
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-SD-NEXT: add v1.2d, v1.2d, v2.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: dup v2.2s, w0
+; CHECK-GI-NEXT: adrp x8, .LCPI3_0
+; CHECK-GI-NEXT: ldr q3, [x8, :lo12:.LCPI3_0]
+; CHECK-GI-NEXT: fmov x8, d3
+; CHECK-GI-NEXT: mov x12, v3.d[1]
+; CHECK-GI-NEXT: sshll v2.2d, v2.2s, #0
+; CHECK-GI-NEXT: fmov x9, d2
+; CHECK-GI-NEXT: mov x11, v2.d[1]
+; CHECK-GI-NEXT: mul x10, x9, x8
+; CHECK-GI-NEXT: mul x8, x9, x8
+; CHECK-GI-NEXT: mul x9, x11, x12
+; CHECK-GI-NEXT: mov v2.d[0], x10
+; CHECK-GI-NEXT: mov v3.d[0], x8
+; CHECK-GI-NEXT: mov v2.d[1], x9
+; CHECK-GI-NEXT: mov v3.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-GI-NEXT: add v1.2d, v1.2d, v3.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <4 x ptr> %p, i32 %q
+ ret <4 x ptr> %d
+}
+
+define <2 x ptr> @v2b(ptr %p, <2 x i32> %q) {
+; CHECK-SD-LABEL: v2b:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: sshll v0.2d, v0.2s, #2
+; CHECK-SD-NEXT: dup v1.2d, x0
+; CHECK-SD-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2b:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI4_0
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI4_0]
+; CHECK-GI-NEXT: fmov x8, d0
+; CHECK-GI-NEXT: fmov x9, d1
+; CHECK-GI-NEXT: mov x10, v0.d[1]
+; CHECK-GI-NEXT: mov x11, v1.d[1]
+; CHECK-GI-NEXT: dup v1.2d, x0
+; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: mul x9, x10, x11
+; CHECK-GI-NEXT: mov v0.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <2 x i32> %q
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3b(ptr %p, <3 x i32> %q) {
+; CHECK-LABEL: v3b:
+; CHECK: // %bb.0:
+; CHECK-NEXT: dup v1.2d, x0
+; CHECK-NEXT: sshll v2.2d, v0.2s, #2
+; CHECK-NEXT: mov w8, #2 // =0x2
+; CHECK-NEXT: sshll2 v3.2d, v0.4s, #0
+; CHECK-NEXT: add v0.2d, v1.2d, v2.2d
+; CHECK-NEXT: fmov d1, x8
+; CHECK-NEXT: ushl d2, d3, d1
+; CHECK-NEXT: fmov d3, x0
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: add d2, d3, d2
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, <3 x i32> %q
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4b(ptr %p, <4 x i32> %q) {
+; CHECK-SD-LABEL: v4b:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: sshll2 v1.2d, v0.4s, #2
+; CHECK-SD-NEXT: dup v2.2d, x0
+; CHECK-SD-NEXT: sshll v0.2d, v0.2s, #2
+; CHECK-SD-NEXT: add v1.2d, v2.2d, v1.2d
+; CHECK-SD-NEXT: add v0.2d, v2.2d, v0.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4b:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI6_0
+; CHECK-GI-NEXT: sshll v1.2d, v0.2s, #0
+; CHECK-GI-NEXT: sshll2 v0.2d, v0.4s, #0
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI6_0]
+; CHECK-GI-NEXT: fmov x8, d2
+; CHECK-GI-NEXT: fmov x9, d1
+; CHECK-GI-NEXT: fmov x12, d0
+; CHECK-GI-NEXT: mov x10, v2.d[1]
+; CHECK-GI-NEXT: mov x11, v1.d[1]
+; CHECK-GI-NEXT: mov x13, v0.d[1]
+; CHECK-GI-NEXT: dup v2.2d, x0
+; CHECK-GI-NEXT: mul x9, x9, x8
+; CHECK-GI-NEXT: mul x8, x12, x8
+; CHECK-GI-NEXT: mul x11, x11, x10
+; CHECK-GI-NEXT: mov v0.d[0], x9
+; CHECK-GI-NEXT: mul x10, x13, x10
+; CHECK-GI-NEXT: mov v1.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x11
+; CHECK-GI-NEXT: mov v1.d[1], x10
+; CHECK-GI-NEXT: add v0.2d, v2.2d, v0.2d
+; CHECK-GI-NEXT: add v1.2d, v2.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <4 x i32> %q
+ ret <4 x ptr> %d
+}
+
+
+define ptr @s_10(ptr %p, i32 %q) {
+; CHECK-LABEL: s_10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: add x0, x0, #40
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, i32 10
+ ret ptr %d
+}
+
+define <2 x ptr> @v2_10(<2 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v2_10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov w8, #40 // =0x28
+; CHECK-SD-NEXT: dup v1.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2_10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI8_0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI8_0]
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <2 x ptr> %p, i32 10
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3_10(<3 x ptr> %p, i32 %q) {
+; CHECK-LABEL: v3_10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-NEXT: mov w8, #40 // =0x28
+; CHECK-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-NEXT: dup v3.2d, x8
+; CHECK-NEXT: add d2, d2, d3
+; CHECK-NEXT: add v0.2d, v0.2d, v3.2d
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: ret
+ %d = getelementptr i32, <3 x ptr> %p, i32 10
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4_10(<4 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v4_10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov w8, #40 // =0x28
+; CHECK-SD-NEXT: dup v2.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-SD-NEXT: add v1.2d, v1.2d, v2.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4_10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI10_0
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI10_0]
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-GI-NEXT: add v1.2d, v1.2d, v2.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <4 x ptr> %p, i32 10
+ ret <4 x ptr> %d
+}
+
+define <2 x ptr> @v2b_10(ptr %p, <2 x i32> %q) {
+; CHECK-SD-LABEL: v2b_10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov w8, #40 // =0x28
+; CHECK-SD-NEXT: dup v0.2d, x0
+; CHECK-SD-NEXT: dup v1.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2b_10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: movi v0.2s, #10
+; CHECK-GI-NEXT: adrp x8, .LCPI11_0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI11_0]
+; CHECK-GI-NEXT: fmov x9, d1
+; CHECK-GI-NEXT: mov x11, v1.d[1]
+; CHECK-GI-NEXT: dup v1.2d, x0
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: fmov x8, d0
+; CHECK-GI-NEXT: mov x10, v0.d[1]
+; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: mul x9, x10, x11
+; CHECK-GI-NEXT: mov v0.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <2 x i32> <i32 10, i32 10>
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3b_10(ptr %p, <3 x i32> %q) {
+; CHECK-LABEL: v3b_10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov w8, #40 // =0x28
+; CHECK-NEXT: dup v0.2d, x0
+; CHECK-NEXT: fmov d3, x0
+; CHECK-NEXT: dup v2.2d, x8
+; CHECK-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-NEXT: add d2, d3, d2
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, <3 x i32> <i32 10, i32 10, i32 10>
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4b_10(ptr %p, <4 x i32> %q) {
+; CHECK-SD-LABEL: v4b_10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov w8, #40 // =0x28
+; CHECK-SD-NEXT: dup v0.2d, x0
+; CHECK-SD-NEXT: dup v1.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: mov v1.16b, v0.16b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4b_10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: movi v0.2s, #10
+; CHECK-GI-NEXT: adrp x8, .LCPI13_0
+; CHECK-GI-NEXT: dup v2.2d, x0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI13_0]
+; CHECK-GI-NEXT: fmov x8, d1
+; CHECK-GI-NEXT: mov x12, v1.d[1]
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: mov x11, v0.d[1]
+; CHECK-GI-NEXT: mul x10, x9, x8
+; CHECK-GI-NEXT: mul x8, x9, x8
+; CHECK-GI-NEXT: mul x9, x11, x12
+; CHECK-GI-NEXT: mov v0.d[0], x10
+; CHECK-GI-NEXT: mov v1.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x9
+; CHECK-GI-NEXT: mov v1.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v2.2d, v0.2d
+; CHECK-GI-NEXT: add v1.2d, v2.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <4 x i32> <i32 10, i32 10, i32 10, i32 10>
+ ret <4 x ptr> %d
+}
+
+
+define ptr @s_m10(ptr %p, i32 %q) {
+; CHECK-LABEL: s_m10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: sub x0, x0, #40
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, i32 -10
+ ret ptr %d
+}
+
+define <2 x ptr> @v2_m10(<2 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v2_m10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-SD-NEXT: dup v1.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2_m10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI15_0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI15_0]
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <2 x ptr> %p, i32 -10
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3_m10(<3 x ptr> %p, i32 %q) {
+; CHECK-LABEL: v3_m10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
+; CHECK-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-NEXT: dup v3.2d, x8
+; CHECK-NEXT: add d2, d2, d3
+; CHECK-NEXT: add v0.2d, v0.2d, v3.2d
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: ret
+ %d = getelementptr i32, <3 x ptr> %p, i32 -10
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4_m10(<4 x ptr> %p, i32 %q) {
+; CHECK-SD-LABEL: v4_m10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-SD-NEXT: dup v2.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-SD-NEXT: add v1.2d, v1.2d, v2.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4_m10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI17_0
+; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI17_0]
+; CHECK-GI-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-GI-NEXT: add v1.2d, v1.2d, v2.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, <4 x ptr> %p, i32 -10
+ ret <4 x ptr> %d
+}
+
+define <2 x ptr> @v2b_m10(ptr %p, <2 x i32> %q) {
+; CHECK-SD-LABEL: v2b_m10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-SD-NEXT: dup v1.2d, x0
+; CHECK-SD-NEXT: dup v0.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v2b_m10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mvni v0.2s, #9
+; CHECK-GI-NEXT: adrp x8, .LCPI18_0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI18_0]
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: fmov x9, d1
+; CHECK-GI-NEXT: mov x11, v1.d[1]
+; CHECK-GI-NEXT: dup v1.2d, x0
+; CHECK-GI-NEXT: fmov x8, d0
+; CHECK-GI-NEXT: mov x10, v0.d[1]
+; CHECK-GI-NEXT: mul x8, x8, x9
+; CHECK-GI-NEXT: mul x9, x10, x11
+; CHECK-GI-NEXT: mov v0.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <2 x i32> <i32 -10, i32 -10>
+ ret <2 x ptr> %d
+}
+
+define <3 x ptr> @v3b_m10(ptr %p, <3 x i32> %q) {
+; CHECK-LABEL: v3b_m10:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-NEXT: dup v0.2d, x0
+; CHECK-NEXT: fmov d3, x0
+; CHECK-NEXT: dup v2.2d, x8
+; CHECK-NEXT: add v0.2d, v0.2d, v2.2d
+; CHECK-NEXT: add d2, d3, d2
+; CHECK-NEXT: ext v1.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT: // kill: def $d1 killed $d1 killed $q1
+; CHECK-NEXT: ret
+ %d = getelementptr i32, ptr %p, <3 x i32> <i32 -10, i32 -10, i32 -10>
+ ret <3 x ptr> %d
+}
+
+define <4 x ptr> @v4b_m10(ptr %p, <4 x i32> %q) {
+; CHECK-SD-LABEL: v4b_m10:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov x8, #-40 // =0xffffffffffffffd8
+; CHECK-SD-NEXT: dup v1.2d, x0
+; CHECK-SD-NEXT: dup v0.2d, x8
+; CHECK-SD-NEXT: add v0.2d, v1.2d, v0.2d
+; CHECK-SD-NEXT: mov v1.16b, v0.16b
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: v4b_m10:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: mvni v0.2s, #9
+; CHECK-GI-NEXT: adrp x8, .LCPI20_0
+; CHECK-GI-NEXT: dup v2.2d, x0
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI20_0]
+; CHECK-GI-NEXT: sshll v0.2d, v0.2s, #0
+; CHECK-GI-NEXT: fmov x8, d1
+; CHECK-GI-NEXT: mov x12, v1.d[1]
+; CHECK-GI-NEXT: fmov x9, d0
+; CHECK-GI-NEXT: mov x11, v0.d[1]
+; CHECK-GI-NEXT: mul x10, x9, x8
+; CHECK-GI-NEXT: mul x8, x9, x8
+; CHECK-GI-NEXT: mul x9, x11, x12
+; CHECK-GI-NEXT: mov v0.d[0], x10
+; CHECK-GI-NEXT: mov v1.d[0], x8
+; CHECK-GI-NEXT: mov v0.d[1], x9
+; CHECK-GI-NEXT: mov v1.d[1], x9
+; CHECK-GI-NEXT: add v0.2d, v2.2d, v0.2d
+; CHECK-GI-NEXT: add v1.2d, v2.2d, v1.2d
+; CHECK-GI-NEXT: ret
+ %d = getelementptr i32, ptr %p, <4 x i32> <i32 -10, i32 -10, i32 -10, i32 -10>
+ ret <4 x ptr> %d
+}
diff --git a/llvm/test/MachineVerifier/test_g_unmerge_values.mir b/llvm/test/MachineVerifier/test_g_unmerge_values.mir
index d16854890f7d88..4e5a2b2c2792bb 100644
--- a/llvm/test/MachineVerifier/test_g_unmerge_values.mir
+++ b/llvm/test/MachineVerifier/test_g_unmerge_values.mir
@@ -30,4 +30,9 @@ body: |
; CHECK: Bad machine code: G_UNMERGE_VALUES scalar source operand does not match scalar destination operands
%17:_(s32), %18:_(s32), %19:_(s32) = G_UNMERGE_VALUES %14
+
+ ; CHECK-NOT: Bad machine code
+ %20:_(<4 x p0>) = IMPLICIT_DEF
+ %21:_(<2 x s64>), %22:_(<2 x s64>) = G_UNMERGE_VALUES %20
+ %23:_(s64), %24:_(s64), %25:_(s64), %26:_(s64) = G_UNMERGE_VALUES %20
...
More information about the llvm-commits
mailing list