; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ; RUN: llc -mtriple=aarch64 -mattr=+sve < %s -o - | FileCheck --check-prefixes=CHECK,SVE %s ; RUN: llc -mtriple=aarch64 -mattr=+sve2 < %s -o - | FileCheck --check-prefixes=CHECK,SVE2 %s ; Wrong add/shift amount. Should be 32 for shift of 6. define @neg_urshr_1( %x) { ; CHECK-LABEL: neg_urshr_1: ; CHECK: // %bb.0: ; CHECK-NEXT: add z0.d, z0.d, #16 // =0x10 ; CHECK-NEXT: lsr z0.d, z0.d, #6 ; CHECK-NEXT: ret %add = add nuw nsw %x, splat (i64 16) %sh = lshr %add, splat (i64 6) ret %sh } ; Vector Shift. define @neg_urshr_2( %x, %y) { ; CHECK-LABEL: neg_urshr_2: ; CHECK: // %bb.0: ; CHECK-NEXT: add z0.d, z0.d, #32 // =0x20 ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: lsr z0.d, p0/m, z0.d, z1.d ; CHECK-NEXT: ret %add = add nuw nsw %x, splat (i64 32) %sh = lshr %add, %y ret %sh } ; Vector Add. define @neg_urshr_3( %x, %y) { ; CHECK-LABEL: neg_urshr_3: ; CHECK: // %bb.0: ; CHECK-NEXT: add z0.d, z0.d, z1.d ; CHECK-NEXT: lsr z0.d, z0.d, #6 ; CHECK-NEXT: ret %add = add nuw nsw %x, %y %sh = lshr %add, splat (i64 6) ret %sh } ; Add has two uses. define @neg_urshr_4( %x, ptr %p) { ; CHECK-LABEL: neg_urshr_4: ; CHECK: // %bb.0: ; CHECK-NEXT: mov z1.d, z0.d ; CHECK-NEXT: ptrue p0.d ; CHECK-NEXT: add z1.d, z1.d, #32 // =0x20 ; CHECK-NEXT: lsr z0.d, z1.d, #6 ; CHECK-NEXT: st1d { z1.d }, p0, [x0] ; CHECK-NEXT: ret %add = add nuw nsw %x, splat (i64 32) %sh = lshr %add, splat (i64 6) store %add, ptr %p ret %sh } ; Add can overflow. define @neg_urshr_5( %x) { ; CHECK-LABEL: neg_urshr_5: ; CHECK: // %bb.0: ; CHECK-NEXT: add z0.d, z0.d, #32 // =0x20 ; CHECK-NEXT: lsr z0.d, z0.d, #6 ; CHECK-NEXT: ret %add = add %x, splat (i64 32) %sh = lshr %add, splat (i64 6) ret %sh } define @urshr_i8( %x) { ; SVE-LABEL: urshr_i8: ; SVE: // %bb.0: ; SVE-NEXT: add z0.b, z0.b, #32 // =0x20 ; SVE-NEXT: lsr z0.b, z0.b, #6 ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_i8: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.b ; SVE2-NEXT: urshr z0.b, p0/m, z0.b, #6 ; SVE2-NEXT: ret %add = add nuw nsw %x, splat (i8 32) %sh = lshr %add, splat (i8 6) ret %sh } define @urshr_8_wide_trunc( %x) { ; SVE-LABEL: urshr_8_wide_trunc: ; SVE: // %bb.0: ; SVE-NEXT: uunpkhi z1.h, z0.b ; SVE-NEXT: uunpklo z0.h, z0.b ; SVE-NEXT: add z0.h, z0.h, #32 // =0x20 ; SVE-NEXT: add z1.h, z1.h, #32 // =0x20 ; SVE-NEXT: lsr z1.h, z1.h, #6 ; SVE-NEXT: lsr z0.h, z0.h, #6 ; SVE-NEXT: uzp1 z0.b, z0.b, z1.b ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_8_wide_trunc: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.b ; SVE2-NEXT: urshr z0.b, p0/m, z0.b, #6 ; SVE2-NEXT: ret %ext = zext %x to %add = add nuw nsw %ext, splat (i16 32) %sh = lshr %add, splat (i16 6) %sht = trunc %sh to ret %sht } define @urshr_8_wide_trunc_nomerge( %ext) { ; SVE-LABEL: urshr_8_wide_trunc_nomerge: ; SVE: // %bb.0: ; SVE-NEXT: add z0.h, z0.h, #256 // =0x100 ; SVE-NEXT: add z1.h, z1.h, #256 // =0x100 ; SVE-NEXT: lsr z1.h, z1.h, #9 ; SVE-NEXT: lsr z0.h, z0.h, #9 ; SVE-NEXT: uzp1 z0.b, z0.b, z1.b ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_8_wide_trunc_nomerge: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.h ; SVE2-NEXT: urshr z1.h, p0/m, z1.h, #9 ; SVE2-NEXT: urshr z0.h, p0/m, z0.h, #9 ; SVE2-NEXT: uzp1 z0.b, z0.b, z1.b ; SVE2-NEXT: ret %add = add nuw nsw %ext, splat (i16 256) %sh = lshr %add, splat (i16 9) %sht = trunc %sh to ret %sht } define @urshr_i16( %x) { ; SVE-LABEL: urshr_i16: ; SVE: // %bb.0: ; SVE-NEXT: add z0.h, z0.h, #32 // =0x20 ; SVE-NEXT: lsr z0.h, z0.h, #6 ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_i16: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.h ; SVE2-NEXT: urshr z0.h, p0/m, z0.h, #6 ; SVE2-NEXT: ret %add = add nuw nsw %x, splat (i16 32) %sh = lshr %add, splat (i16 6) ret %sh } define @urshr_16_wide_trunc( %x) { ; SVE-LABEL: urshr_16_wide_trunc: ; SVE: // %bb.0: ; SVE-NEXT: uunpkhi z1.s, z0.h ; SVE-NEXT: uunpklo z0.s, z0.h ; SVE-NEXT: add z0.s, z0.s, #32 // =0x20 ; SVE-NEXT: add z1.s, z1.s, #32 // =0x20 ; SVE-NEXT: lsr z1.s, z1.s, #6 ; SVE-NEXT: lsr z0.s, z0.s, #6 ; SVE-NEXT: uzp1 z0.h, z0.h, z1.h ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_16_wide_trunc: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.h ; SVE2-NEXT: urshr z0.h, p0/m, z0.h, #6 ; SVE2-NEXT: ret %ext = zext %x to %add = add nuw nsw %ext, splat (i32 32) %sh = lshr %add, splat (i32 6) %sht = trunc %sh to ret %sht } define @urshr_16_wide_trunc_nomerge( %ext) { ; SVE-LABEL: urshr_16_wide_trunc_nomerge: ; SVE: // %bb.0: ; SVE-NEXT: mov z2.s, #0x10000 ; SVE-NEXT: add z0.s, z0.s, z2.s ; SVE-NEXT: add z1.s, z1.s, z2.s ; SVE-NEXT: lsr z1.s, z1.s, #17 ; SVE-NEXT: lsr z0.s, z0.s, #17 ; SVE-NEXT: uzp1 z0.h, z0.h, z1.h ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_16_wide_trunc_nomerge: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.s ; SVE2-NEXT: urshr z1.s, p0/m, z1.s, #17 ; SVE2-NEXT: urshr z0.s, p0/m, z0.s, #17 ; SVE2-NEXT: uzp1 z0.h, z0.h, z1.h ; SVE2-NEXT: ret %add = add nuw nsw %ext, splat (i32 65536) %sh = lshr %add, splat (i32 17) %sht = trunc %sh to ret %sht } define @urshr_i32( %x) { ; SVE-LABEL: urshr_i32: ; SVE: // %bb.0: ; SVE-NEXT: add z0.s, z0.s, #32 // =0x20 ; SVE-NEXT: lsr z0.s, z0.s, #6 ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_i32: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.s ; SVE2-NEXT: urshr z0.s, p0/m, z0.s, #6 ; SVE2-NEXT: ret %add = add nuw nsw %x, splat (i32 32) %sh = lshr %add, splat (i32 6) ret %sh } define @urshr_32_wide_trunc( %x) { ; SVE-LABEL: urshr_32_wide_trunc: ; SVE: // %bb.0: ; SVE-NEXT: uunpkhi z1.d, z0.s ; SVE-NEXT: uunpklo z0.d, z0.s ; SVE-NEXT: add z0.d, z0.d, #32 // =0x20 ; SVE-NEXT: add z1.d, z1.d, #32 // =0x20 ; SVE-NEXT: lsr z1.d, z1.d, #6 ; SVE-NEXT: lsr z0.d, z0.d, #6 ; SVE-NEXT: uzp1 z0.s, z0.s, z1.s ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_32_wide_trunc: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.s ; SVE2-NEXT: urshr z0.s, p0/m, z0.s, #6 ; SVE2-NEXT: ret %ext = zext %x to %add = add nuw nsw %ext, splat (i64 32) %sh = lshr %add, splat (i64 6) %sht = trunc %sh to ret %sht } define @urshr_32_wide_trunc_nomerge( %ext) { ; SVE-LABEL: urshr_32_wide_trunc_nomerge: ; SVE: // %bb.0: ; SVE-NEXT: mov z2.d, #0x100000000 ; SVE-NEXT: add z0.d, z0.d, z2.d ; SVE-NEXT: add z1.d, z1.d, z2.d ; SVE-NEXT: lsr z1.d, z1.d, #33 ; SVE-NEXT: lsr z0.d, z0.d, #33 ; SVE-NEXT: uzp1 z0.s, z0.s, z1.s ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_32_wide_trunc_nomerge: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.d ; SVE2-NEXT: urshr z1.d, p0/m, z1.d, #33 ; SVE2-NEXT: urshr z0.d, p0/m, z0.d, #33 ; SVE2-NEXT: uzp1 z0.s, z0.s, z1.s ; SVE2-NEXT: ret %add = add nuw nsw %ext, splat (i64 4294967296) %sh = lshr %add, splat (i64 33) %sht = trunc %sh to ret %sht } define @urshr_i64( %x) { ; SVE-LABEL: urshr_i64: ; SVE: // %bb.0: ; SVE-NEXT: add z0.d, z0.d, #32 // =0x20 ; SVE-NEXT: lsr z0.d, z0.d, #6 ; SVE-NEXT: ret ; ; SVE2-LABEL: urshr_i64: ; SVE2: // %bb.0: ; SVE2-NEXT: ptrue p0.d ; SVE2-NEXT: urshr z0.d, p0/m, z0.d, #6 ; SVE2-NEXT: ret %add = add nuw nsw %x, splat (i64 32) %sh = lshr %add, splat (i64 6) ret %sh }