diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -3213,6 +3213,28 @@ defm SQXTUNT_ZZ : sve2_int_sat_extract_narrow_top<0b10, "sqxtunt", int_aarch64_sve_sqxtunt>; } // End HasSVE2orSME +let Predicates = [HasSVE2orSME] in { + multiclass sraPat { + def : Pat<(add Ty:$Op1, + (Ty (shift (PredTy (SVEAllActive)), + Ty:$Op2, + (Ty (AArch64dup (ShiftTy (cast i32:$Op3))))))), + (DestAdrIns $Op1, $Op2, i32:$Op3)>; + } + + defm : sraPat; + defm : sraPat; + defm : sraPat; + defm : sraPat; + + defm : sraPat; + defm : sraPat; + defm : sraPat; + defm : sraPat; +} + let Predicates = [HasSVE2] in { // SVE2 character match defm MATCH_PPzZZ : sve2_char_match<0b0, "match", int_aarch64_sve_match>; diff --git a/llvm/test/CodeGen/AArch64/sve2-add-shift-to-sra.ll b/llvm/test/CodeGen/AArch64/sve2-add-shift-to-sra.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve2-add-shift-to-sra.ll @@ -0,0 +1,106 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s | FileCheck %s + +target triple = "aarch64-unknown-linux-gnu" + +; USRA + +define @usra_i8( %a, %b) #0 { +; CHECK-LABEL: usra_i8: +; CHECK: // %bb.0: +; CHECK-NEXT: usra z0.b, z1.b, #1 +; CHECK-NEXT: ret + %ins = insertelement poison, i8 1, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = lshr %b, %splat + %add = add %a, %shift + ret %add +} + +define @usra_i16( %a, %b) #0 { +; CHECK-LABEL: usra_i16: +; CHECK: // %bb.0: +; CHECK-NEXT: usra z0.h, z1.h, #2 +; CHECK-NEXT: ret + %ins = insertelement poison, i16 2, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = lshr %b, %splat + %add = add %a, %shift + ret %add +} + +define @usra_i32( %a, %b) #0 { +; CHECK-LABEL: usra_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: usra z0.s, z1.s, #3 +; CHECK-NEXT: ret + %ins = insertelement poison, i32 3, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = lshr %b, %splat + %add = add %a, %shift + ret %add +} + +define @usra_i64( %a, %b) #0 { +; CHECK-LABEL: usra_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: usra z0.d, z1.d, #4 +; CHECK-NEXT: ret + %ins = insertelement poison, i64 4, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = lshr %b, %splat + %add = add %a, %shift + ret %add +} + +; SSRA + +define @ssra_i8( %a, %b) #0 { +; CHECK-LABEL: ssra_i8: +; CHECK: // %bb.0: +; CHECK-NEXT: ssra z0.b, z1.b, #1 +; CHECK-NEXT: ret + %ins = insertelement poison, i8 1, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = ashr %b, %splat + %add = add %a, %shift + ret %add +} + +define @ssra_i16( %a, %b) #0 { +; CHECK-LABEL: ssra_i16: +; CHECK: // %bb.0: +; CHECK-NEXT: ssra z0.h, z1.h, #2 +; CHECK-NEXT: ret + %ins = insertelement poison, i16 2, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = ashr %b, %splat + %add = add %a, %shift + ret %add +} + +define @ssra_i32( %a, %b) #0 { +; CHECK-LABEL: ssra_i32: +; CHECK: // %bb.0: +; CHECK-NEXT: ssra z0.s, z1.s, #3 +; CHECK-NEXT: ret + %ins = insertelement poison, i32 3, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = ashr %b, %splat + %add = add %a, %shift + ret %add +} + +define @ssra_i64( %a, %b) #0 { +; CHECK-LABEL: ssra_i64: +; CHECK: // %bb.0: +; CHECK-NEXT: ssra z0.d, z1.d, #4 +; CHECK-NEXT: ret + %ins = insertelement poison, i64 4, i32 0 + %splat = shufflevector %ins, poison, zeroinitializer + %shift = ashr %b, %splat + %add = add %a, %shift + ret %add +} + +attributes #0 = { "target-features"="+sve,+sve2" }