diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -1146,6 +1146,11 @@ llvm_i32_ty], [IntrNoMem, ImmArg<2>]>; + class SVE2_CONFLICT_DETECT_Intrinsic + : Intrinsic<[llvm_anyvector_ty], + [LLVMAnyPointerType, + LLVMMatchType<1>]>; + class SVE2_3VectorArg_Indexed_Intrinsic : Intrinsic<[llvm_anyvector_ty], [LLVMMatchType<0>, @@ -2167,3 +2172,16 @@ def int_aarch64_sve_bgrp_x : AdvSIMD_2VectorArg_Intrinsic; } + +// +// SVE2 - Contiguous conflict detection +// + +def int_aarch64_sve_whilerw_b : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilerw_h : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilerw_s : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilerw_d : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilewr_b : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilewr_h : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilewr_s : SVE2_CONFLICT_DETECT_Intrinsic; +def int_aarch64_sve_whilewr_d : SVE2_CONFLICT_DETECT_Intrinsic; 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 @@ -1975,8 +1975,8 @@ defm WHILEHI_PXX : sve_int_while8_rr<0b101, "whilehi", int_aarch64_sve_whilehi>; // SVE2 pointer conflict compare - defm WHILEWR_PXX : sve2_int_while_rr<0b0, "whilewr">; - defm WHILERW_PXX : sve2_int_while_rr<0b1, "whilerw">; + defm WHILEWR_PXX : sve2_int_while_rr<0b0, "whilewr", "int_aarch64_sve_whilewr">; + defm WHILERW_PXX : sve2_int_while_rr<0b1, "whilerw", "int_aarch64_sve_whilerw">; } let Predicates = [HasSVE2AES] in { diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -4385,11 +4385,17 @@ let Defs = [NZCV]; } -multiclass sve2_int_while_rr rw, string asm> { +multiclass sve2_int_while_rr rw, string asm, string op> { def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>; def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>; def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>; def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>; + + def : SVE_2_Op_Pat(op # _b), i64, i64, !cast(NAME # _B)>; + def : SVE_2_Op_Pat(op # _h), i64, i64, !cast(NAME # _H)>; + def : SVE_2_Op_Pat(op # _s), i64, i64, !cast(NAME # _S)>; + def : SVE_2_Op_Pat(op # _d), i64, i64, !cast(NAME # _D)>; + } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/AArch64/sve2-intrinsics-contiguous-conflict-detection.ll b/llvm/test/CodeGen/AArch64/sve2-intrinsics-contiguous-conflict-detection.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve2-intrinsics-contiguous-conflict-detection.ll @@ -0,0 +1,139 @@ +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve2 -asm-verbose=0 < %s | FileCheck %s + +; +; WHILERW +; + +define @whilerw_i8(i8* %a, i8* %b) { +; CHECK-LABEL: whilerw_i8: +; CHECK: whilerw p0.b, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.b.nx16i1(i8* %a, i8* %b) + ret %out +} + +define @whilerw_i16(i16* %a, i16* %b) { +; CHECK-LABEL: whilerw_i16: +; CHECK: whilerw p0.h, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.h.nx8i1(i16* %a, i16* %b) + ret %out +} + +define @whilerw_i32(i32* %a, i32* %b) { +; CHECK-LABEL: whilerw_i32: +; CHECK: whilerw p0.s, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.s.nx4i1(i32* %a, i32* %b) + ret %out +} + +define @whilerw_i64(i64* %a, i64* %b) { +; CHECK-LABEL: whilerw_i64: +; CHECK: whilerw p0.d, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.d.nx2i1(i64* %a, i64* %b) + ret %out +} + +define @whilerw_half(half* %a, half* %b) { +; CHECK-LABEL: whilerw_half: +; CHECK: whilerw p0.h, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.h.nx8i1.f16.f16(half* %a, half* %b) + ret %out +} + +define @whilerw_float(float* %a, float* %b) { +; CHECK-LABEL: whilerw_float: +; CHECK: whilerw p0.s, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.s.nx4i1.f32.f32(float* %a, float* %b) + ret %out +} + +define @whilerw_double(double* %a, double* %b) { +; CHECK-LABEL: whilerw_double: +; CHECK: whilerw p0.d, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilerw.d.nx2i1.f64.f64(double* %a, double* %b) + ret %out +} + +; +; WHILEWR +; + +define @whilewr_i8(i8* %a, i8* %b) { +; CHECK-LABEL: whilewr_i8: +; CHECK: whilewr p0.b, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.b.nx16i1(i8* %a, i8* %b) + ret %out +} + +define @whilewr_i16(i16* %a, i16* %b) { +; CHECK-LABEL: whilewr_i16: +; CHECK: whilewr p0.h, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.h.nx8i1(i16* %a, i16* %b) + ret %out +} + +define @whilewr_i32(i32* %a, i32* %b) { +; CHECK-LABEL: whilewr_i32: +; CHECK: whilewr p0.s, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.s.nx4i1(i32* %a, i32* %b) + ret %out +} + +define @whilewr_i64(i64* %a, i64* %b) { +; CHECK-LABEL: whilewr_i64: +; CHECK: whilewr p0.d, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.d.nx2i1(i64* %a, i64* %b) + ret %out +} + +define @whilewr_half(half* %a, half* %b) { +; CHECK-LABEL: whilewr_half: +; CHECK: whilewr p0.h, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.h.nx8i1.f16.f16(half* %a, half* %b) + ret %out +} + +define @whilewr_float(float* %a, float* %b) { +; CHECK-LABEL: whilewr_float: +; CHECK: whilewr p0.s, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.s.nx4i1.f32.f32(float* %a, float* %b) + ret %out +} + +define @whilewr_double(double* %a, double* %b) { +; CHECK-LABEL: whilewr_double: +; CHECK: whilewr p0.d, x0, x1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.whilewr.d.nx2i1.f64.f64(double* %a, double* %b) + ret %out +} + +declare @llvm.aarch64.sve.whilerw.b.nx16i1(i8* %a, i8* %b) +declare @llvm.aarch64.sve.whilerw.h.nx8i1(i16* %a, i16* %b) +declare @llvm.aarch64.sve.whilerw.s.nx4i1(i32* %a, i32* %b) +declare @llvm.aarch64.sve.whilerw.d.nx2i1(i64* %a, i64* %b) + +declare @llvm.aarch64.sve.whilerw.h.nx8i1.f16.f16(half* %a, half* %b) +declare @llvm.aarch64.sve.whilerw.s.nx4i1.f32.f32(float* %a, float* %b) +declare @llvm.aarch64.sve.whilerw.d.nx2i1.f64.f64(double* %a, double* %b) + +declare @llvm.aarch64.sve.whilewr.b.nx16i1(i8* %a, i8* %b) +declare @llvm.aarch64.sve.whilewr.h.nx8i1(i16* %a, i16* %b) +declare @llvm.aarch64.sve.whilewr.s.nx4i1(i32* %a, i32* %b) +declare @llvm.aarch64.sve.whilewr.d.nx2i1(i64* %a, i64* %b) + +declare @llvm.aarch64.sve.whilewr.h.nx8i1.f16.f16(half* %a, half* %b) +declare @llvm.aarch64.sve.whilewr.s.nx4i1.f32.f32(float* %a, float* %b) +declare @llvm.aarch64.sve.whilewr.d.nx2i1.f64.f64(double* %a, double* %b)