diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 6fdcaec86340c..c10653e05841c 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -3845,6 +3845,10 @@ let Predicates = [HasSVE2orSME] in { // SVE2 extract vector (immediate offset, constructive) def EXT_ZZI_B : sve2_int_perm_extract_i_cons<"ext">; + let AddedComplexity = 2 in { + def : Pat<(nxv16i8 (AArch64ext nxv16i8:$zn1, nxv16i8:$zn2, (i32 imm0_255:$imm))), + (EXT_ZZI_B (REG_SEQUENCE ZPR2, $zn1, zsub0, $zn2, zsub1), imm0_255:$imm)>; + } } // End HasSVE2orSME let Predicates = [HasSVE2] in { diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll index fec255b712441..3096b50988476 100644 --- a/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll +++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-perm-select.ll @@ -628,10 +628,17 @@ define dso_local @dupq_f16_repeat_complex(half %x, half %y) } define @ext_i8( %a, %b) { -; CHECK-LABEL: ext_i8: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #255 -; CHECK-NEXT: ret +; SVE-LABEL: ext_i8: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #255 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_i8: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #255 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv16i8( %a, %b, i32 255) @@ -639,10 +646,17 @@ define @ext_i8( %a, %b) } define @ext_i16( %a, %b) { -; CHECK-LABEL: ext_i16: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #0 -; CHECK-NEXT: ret +; SVE-LABEL: ext_i16: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #0 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_i16: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #0 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv8i16( %a, %b, i32 0) @@ -650,10 +664,17 @@ define @ext_i16( %a, %b) } define @ext_i32( %a, %b) { -; CHECK-LABEL: ext_i32: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #4 -; CHECK-NEXT: ret +; SVE-LABEL: ext_i32: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #4 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_i32: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #4 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv4i32( %a, %b, i32 1) @@ -661,10 +682,17 @@ define @ext_i32( %a, %b) } define @ext_i64( %a, %b) { -; CHECK-LABEL: ext_i64: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #16 -; CHECK-NEXT: ret +; SVE-LABEL: ext_i64: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #16 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_i64: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #16 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv2i64( %a, %b, i32 2) @@ -672,10 +700,17 @@ define @ext_i64( %a, %b) } define @ext_bf16( %a, %b) #0 { -; CHECK-LABEL: ext_bf16: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #6 -; CHECK-NEXT: ret +; SVE-LABEL: ext_bf16: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #6 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_bf16: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #6 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv8bf16( %a, %b, i32 3) @@ -683,10 +718,17 @@ define @ext_bf16( %a, @ext_f16( %a, %b) { -; CHECK-LABEL: ext_f16: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #6 -; CHECK-NEXT: ret +; SVE-LABEL: ext_f16: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #6 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_f16: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #6 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv8f16( %a, %b, i32 3) @@ -694,10 +736,17 @@ define @ext_f16( %a, } define @ext_f32( %a, %b) { -; CHECK-LABEL: ext_f32: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #16 -; CHECK-NEXT: ret +; SVE-LABEL: ext_f32: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #16 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_f32: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #16 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv4f32( %a, %b, i32 4) @@ -705,10 +754,17 @@ define @ext_f32( %a, @ext_f64( %a, %b) { -; CHECK-LABEL: ext_f64: -; CHECK: // %bb.0: -; CHECK-NEXT: ext z0.b, z0.b, z1.b, #40 -; CHECK-NEXT: ret +; SVE-LABEL: ext_f64: +; SVE: // %bb.0: +; SVE-NEXT: ext z0.b, z0.b, z1.b, #40 +; SVE-NEXT: ret +; +; SVE2-LABEL: ext_f64: +; SVE2: // %bb.0: +; SVE2-NEXT: // kill: def $z1 killed $z1 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: // kill: def $z0 killed $z0 killed $z0_z1 def $z0_z1 +; SVE2-NEXT: ext z0.b, { z0.b, z1.b }, #40 +; SVE2-NEXT: ret %out = call @llvm.aarch64.sve.ext.nxv2f64( %a, %b, i32 5)