// Extensions
getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
- .legalForCartesianProduct({s8, s16, s32, s64}, {s1, s8, s16, s32});
+ .legalForCartesianProduct({s8, s16, s32, s64}, {s1, s8, s16, s32})
+ .legalFor({v8s16, v8s8});
getActionDefinitionsBuilder(G_TRUNC).alwaysLegal();
$w0 = COPY %3(s32)
...
+---
+name: test_zext_v8s16_from_v8s8
+alignment: 2
+tracksRegLiveness: true
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+ ; CHECK-LABEL: name: test_zext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr(<8 x s8>) = COPY $d0
+ ; CHECK: [[ZEXT:%[0-9]+]]:_(<8 x s16>) = G_ZEXT [[COPY]](<8 x s8>)
+ ; CHECK: $q0 = COPY [[ZEXT]](<8 x s16>)
+ ; CHECK: RET_ReallyLR implicit $q0
+ %1:fpr(<8 x s8>) = COPY $d0
+ %2:_(<8 x s16>) = G_ZEXT %1(<8 x s8>)
+ $q0 = COPY %2(<8 x s16>)
+ RET_ReallyLR implicit $q0
+
+...
+---
+name: test_sext_v8s16_from_v8s8
+alignment: 2
+tracksRegLiveness: true
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+ ; CHECK-LABEL: name: test_sext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr(<8 x s8>) = COPY $d0
+ ; CHECK: [[SEXT:%[0-9]+]]:_(<8 x s16>) = G_SEXT [[COPY]](<8 x s8>)
+ ; CHECK: $q0 = COPY [[SEXT]](<8 x s16>)
+ ; CHECK: RET_ReallyLR implicit $q0
+ %1:fpr(<8 x s8>) = COPY $d0
+ %2:_(<8 x s16>) = G_SEXT %1(<8 x s8>)
+ $q0 = COPY %2(<8 x s16>)
+ RET_ReallyLR implicit $q0
+
+...
+---
+name: test_anyext_v8s16_from_v8s8
+alignment: 2
+tracksRegLiveness: true
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+ ; CHECK-LABEL: name: test_anyext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr(<8 x s8>) = COPY $d0
+ ; CHECK: [[ANYEXT:%[0-9]+]]:_(<8 x s16>) = G_ANYEXT [[COPY]](<8 x s8>)
+ ; CHECK: $q0 = COPY [[ANYEXT]](<8 x s16>)
+ ; CHECK: RET_ReallyLR implicit $q0
+ %1:fpr(<8 x s8>) = COPY $d0
+ %2:_(<8 x s16>) = G_ANYEXT %1(<8 x s8>)
+ $q0 = COPY %2(<8 x s16>)
+ RET_ReallyLR implicit $q0
define void @anyext_s64_from_s32() { ret void }
define void @anyext_s32_from_s8() { ret void }
+ define void @anyext_v8s16_from_v8s8() { ret void }
define void @zext_s64_from_s32() { ret void }
define void @zext_s32_from_s16() { ret void }
define void @zext_s32_from_s8() { ret void }
define void @zext_s16_from_s8() { ret void }
+ define void @zext_v8s16_from_v8s8() { ret void }
define void @sext_s64_from_s32() { ret void }
define void @sext_s32_from_s16() { ret void }
define void @sext_s32_from_s8() { ret void }
define void @sext_s16_from_s8() { ret void }
+ define void @sext_v8s16_from_v8s8() { ret void }
...
---
$w0 = COPY %1(s32)
...
+---
+name: anyext_v8s16_from_v8s8
+alignment: 2
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: fpr }
+ - { id: 1, class: fpr }
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: anyext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK: [[USHLLv8i8_shift:%[0-9]+]]:fpr128 = USHLLv8i8_shift [[COPY]], 0
+ ; CHECK: $q0 = COPY [[USHLLv8i8_shift]]
+ ; CHECK: RET_ReallyLR implicit $q0
+ %0:fpr(<8 x s8>) = COPY $d0
+ %1:fpr(<8 x s16>) = G_ANYEXT %0(<8 x s8>)
+ $q0 = COPY %1(<8 x s16>)
+ RET_ReallyLR implicit $q0
+
---
name: zext_s64_from_s32
legalized: true
$w0 = COPY %3(s32)
...
+---
+name: zext_v8s16_from_v8s8
+alignment: 2
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: fpr }
+ - { id: 1, class: fpr }
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: zext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK: [[USHLLv8i8_shift:%[0-9]+]]:fpr128 = USHLLv8i8_shift [[COPY]], 0
+ ; CHECK: $q0 = COPY [[USHLLv8i8_shift]]
+ ; CHECK: RET_ReallyLR implicit $q0
+ %0:fpr(<8 x s8>) = COPY $d0
+ %1:fpr(<8 x s16>) = G_ZEXT %0(<8 x s8>)
+ $q0 = COPY %1(<8 x s16>)
+ RET_ReallyLR implicit $q0
+
+...
+
---
name: sext_s64_from_s32
legalized: true
%3:gpr(s32) = G_ANYEXT %1
$w0 = COPY %3(s32)
...
+
+---
+name: sext_v8s16_from_v8s8
+alignment: 2
+legalized: true
+regBankSelected: true
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: fpr }
+ - { id: 1, class: fpr }
+machineFunctionInfo: {}
+body: |
+ bb.0:
+ liveins: $d0
+
+ ; CHECK-LABEL: name: sext_v8s16_from_v8s8
+ ; CHECK: liveins: $d0
+ ; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK: [[SSHLLv8i8_shift:%[0-9]+]]:fpr128 = SSHLLv8i8_shift [[COPY]], 0
+ ; CHECK: $q0 = COPY [[SSHLLv8i8_shift]]
+ ; CHECK: RET_ReallyLR implicit $q0
+ %0:fpr(<8 x s8>) = COPY $d0
+ %1:fpr(<8 x s16>) = G_SEXT %0(<8 x s8>)
+ $q0 = COPY %1(<8 x s16>)
+ RET_ReallyLR implicit $q0
+
+...
; RUN: llc < %s -mtriple=arm64-eabi -aarch64-neon-syntax=apple | FileCheck %s
+; RUN: llc < %s -global-isel -global-isel-abort=2 -pass-remarks-missed=gisel* -mtriple=arm64-eabi -aarch64-neon-syntax=apple 2>&1 | FileCheck %s --check-prefixes=GISEL,FALLBACK
-
+; FALLBACK-NOT: remark:{{.*}}(<8 x s16>) = G_ZEXT %4:_(<8 x s8>)
+; FALLBACK-NOT: remark:{{.*}} sabdl8h
define <8 x i16> @sabdl8h(<8 x i8>* %A, <8 x i8>* %B) nounwind {
;CHECK-LABEL: sabdl8h:
;CHECK: sabdl.8h
+;GISEL-LABEL: sabdl8h:
+;GISEL: sabdl.8h
%tmp1 = load <8 x i8>, <8 x i8>* %A
%tmp2 = load <8 x i8>, <8 x i8>* %B
%tmp3 = call <8 x i8> @llvm.aarch64.neon.sabd.v8i8(<8 x i8> %tmp1, <8 x i8> %tmp2)