; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-ISEL
; RUN: llc -mtriple=aarch64 -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GLOBAL
define i64 @extract_v2i64(<2 x i64> %x, i32 %y) {
; CHECK-ISEL-LABEL: extract_v2i64:
; CHECK-ISEL: // %bb.0:
; CHECK-ISEL-NEXT: mov x0, v0.d[1]
; CHECK-ISEL-NEXT: ret
;
; CHECK-GLOBAL-LABEL: extract_v2i64:
; CHECK-GLOBAL: // %bb.0:
; CHECK-GLOBAL-NEXT: mov d0, v0.d[1]
; CHECK-GLOBAL-NEXT: fmov x0, d0
; CHECK-GLOBAL-NEXT: ret
%ext = extractelement <2 x i64> %x, i32 1
ret i64 %ext
}
define i64 @extract_v1i64(<1 x i64> %x, i32 %y) {
; CHECK-ISEL-LABEL: extract_v1i64:
; CHECK-ISEL: // %bb.0:
; CHECK-ISEL-NEXT: ret
;
; CHECK-GLOBAL-LABEL: extract_v1i64:
; CHECK-GLOBAL: // %bb.0:
; CHECK-GLOBAL-NEXT: fmov x0, d0
; CHECK-GLOBAL-NEXT: ret
%ext = extractelement <1 x i64> %x, i32 1
ret i64 %ext
}
define i32 @extract_v4i32(<4 x i32> %x, i32 %y) {
; CHECK-ISEL-LABEL: extract_v4i32:
; CHECK-ISEL: // %bb.0:
; CHECK-ISEL-NEXT: mov w0, v0.s[1]
; CHECK-ISEL-NEXT: ret
;
; CHECK-GLOBAL-LABEL: extract_v4i32:
; CHECK-GLOBAL: // %bb.0:
; CHECK-GLOBAL-NEXT: mov s0, v0.s[1]
; CHECK-GLOBAL-NEXT: fmov w0, s0
; CHECK-GLOBAL-NEXT: ret
%ext = extractelement <4 x i32> %x, i32 1
ret i32 %ext
}
define i32 @extract_v2i32(<2 x i32> %x, i32 %y) {
; CHECK-ISEL-LABEL: extract_v2i32:
; CHECK-ISEL: // %bb.0:
; CHECK-ISEL-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-ISEL-NEXT: mov w0, v0.s[1]
; CHECK-ISEL-NEXT: ret
;
; CHECK-GLOBAL-LABEL: extract_v2i32:
; CHECK-GLOBAL: // %bb.0:
; CHECK-GLOBAL-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-GLOBAL-NEXT: mov s0, v0.s[1]
; CHECK-GLOBAL-NEXT: fmov w0, s0
; CHECK-GLOBAL-NEXT: ret
%ext = extractelement <2 x i32> %x, i32 1
ret i32 %ext
}
define i16 @extract_v8i16(<8 x i16> %x, i32 %y) {
; CHECK-LABEL: extract_v8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.h[1]
; CHECK-NEXT: ret
%ext = extractelement <8 x i16> %x, i32 1
ret i16 %ext
}
define i16 @extract_v4i16(<4 x i16> %x, i32 %y) {
; CHECK-LABEL: extract_v4i16:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.h[1]
; CHECK-NEXT: ret
%ext = extractelement <4 x i16> %x, i32 1
ret i16 %ext
}
define i8 @extract_v16i8(<16 x i8> %x, i32 %y) {
; CHECK-LABEL: extract_v16i8:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.b[1]
; CHECK-NEXT: ret
%ext = extractelement <16 x i8> %x, i32 1
ret i8 %ext
}
define i8 @extract_v8i8(<8 x i8> %x, i32 %y) {
; CHECK-LABEL: extract_v8i8:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.b[1]
; CHECK-NEXT: ret
%ext = extractelement <8 x i8> %x, i32 1
ret i8 %ext
}
define i64 @sv2i32i64(<2 x i32> %x) {
; CHECK-LABEL: sv2i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov x0, v0.s[1]
; CHECK-NEXT: ret
%e = extractelement <2 x i32> %x, i64 1
%s = sext i32 %e to i64
ret i64 %s
}
define i64 @sv4i32i64(<4 x i32> %x) {
; CHECK-LABEL: sv4i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: smov x0, v0.s[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i32> %x, i64 2
%s = sext i32 %e to i64
ret i64 %s
}
define i64 @sv4i16i64(<4 x i16> %x) {
; CHECK-LABEL: sv4i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov x0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i16> %x, i64 2
%s = sext i16 %e to i64
ret i64 %s
}
define i64 @sv8i16i64(<8 x i16> %x) {
; CHECK-LABEL: sv8i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: smov x0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = sext i16 %e to i64
ret i64 %s
}
define i64 @sv8i8i64(<8 x i8> %x) {
; CHECK-LABEL: sv8i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov x0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = sext i8 %e to i64
ret i64 %s
}
define i64 @sv16i8i64(<16 x i8> %x) {
; CHECK-LABEL: sv16i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: smov x0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = sext i8 %e to i64
ret i64 %s
}
define i32 @sv8i16i32(<8 x i16> %x) {
; CHECK-LABEL: sv8i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: smov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = sext i16 %e to i32
ret i32 %s
}
define i32 @sv4i16i32(<4 x i16> %x) {
; CHECK-LABEL: sv4i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i16> %x, i64 2
%s = sext i16 %e to i32
ret i32 %s
}
define i32 @sv16i8i32(<16 x i8> %x) {
; CHECK-LABEL: sv16i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: smov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = sext i8 %e to i32
ret i32 %s
}
define i32 @sv8i8i32(<8 x i8> %x) {
; CHECK-LABEL: sv8i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = sext i8 %e to i32
ret i32 %s
}
define i16 @sv16i8i16(<16 x i8> %x) {
; CHECK-LABEL: sv16i8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: smov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = sext i8 %e to i16
ret i16 %s
}
define i16 @sv8i8i16(<8 x i8> %x) {
; CHECK-LABEL: sv8i8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = sext i8 %e to i16
ret i16 %s
}
define i64 @zv2i32i64(<2 x i32> %x) {
; CHECK-LABEL: zv2i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: mov w0, v0.s[1]
; CHECK-NEXT: ret
%e = extractelement <2 x i32> %x, i64 1
%s = zext i32 %e to i64
ret i64 %s
}
define i64 @zv4i32i64(<4 x i32> %x) {
; CHECK-LABEL: zv4i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w0, v0.s[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i32> %x, i64 2
%s = zext i32 %e to i64
ret i64 %s
}
define i64 @zv4i16i64(<4 x i16> %x) {
; CHECK-LABEL: zv4i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i16> %x, i64 2
%s = zext i16 %e to i64
ret i64 %s
}
define i64 @zv8i16i64(<8 x i16> %x) {
; CHECK-LABEL: zv8i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = zext i16 %e to i64
ret i64 %s
}
define i64 @zv8i8i64(<8 x i8> %x) {
; CHECK-LABEL: zv8i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = zext i8 %e to i64
ret i64 %s
}
define i64 @zv16i8i64(<16 x i8> %x) {
; CHECK-LABEL: zv16i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = zext i8 %e to i64
ret i64 %s
}
define i32 @zv8i16i32(<8 x i16> %x) {
; CHECK-LABEL: zv8i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = zext i16 %e to i32
ret i32 %s
}
define i32 @zv4i16i32(<4 x i16> %x) {
; CHECK-LABEL: zv4i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.h[2]
; CHECK-NEXT: ret
%e = extractelement <4 x i16> %x, i64 2
%s = zext i16 %e to i32
ret i32 %s
}
define i32 @zv16i8i32(<16 x i8> %x) {
; CHECK-LABEL: zv16i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = zext i8 %e to i32
ret i32 %s
}
define i32 @zv8i8i32(<8 x i8> %x) {
; CHECK-LABEL: zv8i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = zext i8 %e to i32
ret i32 %s
}
define i16 @zv16i8i16(<16 x i8> %x) {
; CHECK-LABEL: zv16i8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <16 x i8> %x, i64 2
%s = zext i8 %e to i16
ret i16 %s
}
define i16 @zv8i8i16(<8 x i8> %x) {
; CHECK-LABEL: zv8i8i16:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w0, v0.b[2]
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = zext i8 %e to i16
ret i16 %s
}
define i32 @both_i16i32(<8 x i16> %x) {
; CHECK-LABEL: both_i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w8, v0.h[2]
; CHECK-NEXT: smov w9, v0.h[2]
; CHECK-NEXT: eor w0, w8, w9
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = zext i16 %e to i32
%t = sext i16 %e to i32
%u = xor i32 %s, %t
ret i32 %u
}
define i32 @redundant_i16i32(<8 x i16> %x) {
; CHECK-LABEL: redundant_i16i32:
; CHECK: // %bb.0:
; CHECK-NEXT: smov w8, v0.h[2]
; CHECK-NEXT: eor w0, w8, w8, lsl #16
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = sext i16 %e to i32
%t = shl i32 %s, 16
%u = xor i32 %s, %t
ret i32 %u
}
define i32 @both_i8i32(<8 x i8> %x) {
; CHECK-LABEL: both_i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w8, v0.b[2]
; CHECK-NEXT: smov w9, v0.b[2]
; CHECK-NEXT: eor w0, w8, w9
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = zext i8 %e to i32
%t = sext i8 %e to i32
%u = xor i32 %s, %t
ret i32 %u
}
define i32 @redundant_i8i32(<8 x i8> %x) {
; CHECK-LABEL: redundant_i8i32:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov w8, v0.b[2]
; CHECK-NEXT: eor w0, w8, w8, lsl #24
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = sext i8 %e to i32
%t = shl i32 %s, 24
%u = xor i32 %s, %t
ret i32 %u
}
define i64 @both_i32i64(<4 x i32> %x) {
; CHECK-LABEL: both_i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: mov w8, v0.s[2]
; CHECK-NEXT: smov x9, v0.s[2]
; CHECK-NEXT: eor x0, x8, x9
; CHECK-NEXT: ret
%e = extractelement <4 x i32> %x, i64 2
%s = zext i32 %e to i64
%t = sext i32 %e to i64
%u = xor i64 %s, %t
ret i64 %u
}
define i64 @redundant_i32i64(<4 x i32> %x) {
; CHECK-LABEL: redundant_i32i64:
; CHECK: // %bb.0:
; CHECK-NEXT: smov x8, v0.s[2]
; CHECK-NEXT: eor x0, x8, x8, lsl #32
; CHECK-NEXT: ret
%e = extractelement <4 x i32> %x, i64 2
%s = sext i32 %e to i64
%t = shl i64 %s, 32
%u = xor i64 %s, %t
ret i64 %u
}
define i64 @both_i16i64(<8 x i16> %x) {
; CHECK-LABEL: both_i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: umov w8, v0.h[2]
; CHECK-NEXT: smov x9, v0.h[2]
; CHECK-NEXT: eor x0, x8, x9
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = zext i16 %e to i64
%t = sext i16 %e to i64
%u = xor i64 %s, %t
ret i64 %u
}
define i64 @redundant_i16i64(<8 x i16> %x) {
; CHECK-LABEL: redundant_i16i64:
; CHECK: // %bb.0:
; CHECK-NEXT: smov x8, v0.h[2]
; CHECK-NEXT: eor x0, x8, x8, lsl #48
; CHECK-NEXT: ret
%e = extractelement <8 x i16> %x, i64 2
%s = sext i16 %e to i64
%t = shl i64 %s, 48
%u = xor i64 %s, %t
ret i64 %u
}
define i64 @both_i8i64(<8 x i8> %x) {
; CHECK-LABEL: both_i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: umov w8, v0.b[2]
; CHECK-NEXT: smov x9, v0.b[2]
; CHECK-NEXT: eor x0, x8, x9
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = zext i8 %e to i64
%t = sext i8 %e to i64
%u = xor i64 %s, %t
ret i64 %u
}
define i64 @redundant_i8i64(<8 x i8> %x) {
; CHECK-LABEL: redundant_i8i64:
; CHECK: // %bb.0:
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-NEXT: smov x8, v0.b[2]
; CHECK-NEXT: eor x0, x8, x8, lsl #56
; CHECK-NEXT: ret
%e = extractelement <8 x i8> %x, i64 2
%s = sext i8 %e to i64
%t = shl i64 %s, 56
%u = xor i64 %s, %t
ret i64 %u
}