diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-brk.ll b/llvm/test/CodeGen/AArch64/sve-ptest-removal-brk.ll --- a/llvm/test/CodeGen/AArch64/sve-ptest-removal-brk.ll +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-brk.ll @@ -3,6 +3,19 @@ ; Test that redundant ptest instruction is removed when using a flag setting brk +define i32 @brkpa( %pg, %a, %b) { +; CHECK-LABEL: brkpa: +; CHECK: // %bb.0: +; CHECK-NEXT: brkpa p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.brkpa.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + %conv = zext i1 %2 to i32 + ret i32 %conv +} + define i32 @brkpb( %pg, %a, %b) { ; CHECK-LABEL: brkpb: ; CHECK: // %bb.0: @@ -15,6 +28,19 @@ ret i32 %conv } +define i32 @brka( %pg, %a) { +; CHECK-LABEL: brka: +; CHECK: // %bb.0: +; CHECK-NEXT: brka p1.b, p0/z, p1.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.brka.z.nxv16i1( %pg, %a) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + %conv = zext i1 %2 to i32 + ret i32 %conv +} + define i32 @brkb( %pg, %a) { ; CHECK-LABEL: brkb: ; CHECK: // %bb.0: @@ -55,6 +81,19 @@ ; Test that ptest instruction is not removed when using a non-flag setting brk +define i32 @brkpa_neg( %pg, %a, %b) { +; CHECK-LABEL: brkpa_neg: +; CHECK: // %bb.0: +; CHECK-NEXT: brkpa p0.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p1, p0.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.brkpa.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %a, %1) + %conv = zext i1 %2 to i32 + ret i32 %conv +} + define i32 @brkpb_neg( %pg, %a, %b) { ; CHECK-LABEL: brkpb_neg: ; CHECK: // %bb.0: @@ -68,6 +107,19 @@ ret i32 %conv } +define i32 @brka_neg( %pg, %a) { +; CHECK-LABEL: brka_neg: +; CHECK: // %bb.0: +; CHECK-NEXT: brka p0.b, p0/z, p1.b +; CHECK-NEXT: ptest p1, p0.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.brka.z.nxv16i1( %pg, %a) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %a, %1) + %conv = zext i1 %2 to i32 + ret i32 %conv +} + define i32 @brkb_neg( %pg, %a) { ; CHECK-LABEL: brkb_neg: ; CHECK: // %bb.0: @@ -94,7 +146,9 @@ ret i32 %conv } +declare @llvm.aarch64.sve.brkpa.z.nxv16i1(, , ) declare @llvm.aarch64.sve.brkpb.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.brka.z.nxv16i1(, ) declare @llvm.aarch64.sve.brkb.z.nxv16i1(, ) declare @llvm.aarch64.sve.brkn.z.nxv16i1(, , ) declare i1 @llvm.aarch64.sve.ptest.any.nxv16i1(, ) diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-log.ll b/llvm/test/CodeGen/AArch64/sve-ptest-removal-log.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-log.ll @@ -0,0 +1,98 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve %s -o - | FileCheck %s + +; Test flag-setting bitwise logical instructions are used and redundant ptest +; instruction is removed. + +define i1 @and( %pg, %a, %b) { +; CHECK-LABEL: and: +; CHECK: // %bb.0: +; CHECK-NEXT: and p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.and.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @bic( %pg, %a, %b) { +; CHECK-LABEL: bic: +; CHECK: // %bb.0: +; CHECK-NEXT: bic p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.bic.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @eor( %pg, %a, %b) { +; CHECK-LABEL: eor: +; CHECK: // %bb.0: +; CHECK-NEXT: eor p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.eor.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @nand( %pg, %a, %b) { +; CHECK-LABEL: nand: +; CHECK: // %bb.0: +; CHECK-NEXT: nand p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.nand.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @nor( %pg, %a, %b) { +; CHECK-LABEL: nor: +; CHECK: // %bb.0: +; CHECK-NEXT: nor p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.nor.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @orn( %pg, %a, %b) { +; CHECK-LABEL: orn: +; CHECK: // %bb.0: +; CHECK-NEXT: orn p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.orn.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +define i1 @orr( %pg, %a, %b) { +; CHECK-LABEL: orr: +; CHECK: // %bb.0: +; CHECK-NEXT: orr p1.b, p0/z, p1.b, p2.b +; CHECK-NEXT: ptest p0, p1.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.orr.z.nxv16i1( %pg, %a, %b) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %pg, %1) + ret i1 %2 +} + +declare @llvm.aarch64.sve.and.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.bic.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.eor.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.nand.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.nor.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.orn.z.nxv16i1(, , ) +declare @llvm.aarch64.sve.orr.z.nxv16i1(, , ) +declare i1 @llvm.aarch64.sve.ptest.any.nxv16i1(, ) diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-ptrue.ll b/llvm/test/CodeGen/AArch64/sve-ptest-removal-ptrue.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-ptrue.ll @@ -0,0 +1,17 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve %s -o - | FileCheck %s + +define i1 @ptrue() { +; CHECK-LABEL: ptrue: +; CHECK: // %bb.0: +; CHECK-NEXT: ptrue p0.b, pow2 +; CHECK-NEXT: ptest p0, p0.b +; CHECK-NEXT: cset w0, ne +; CHECK-NEXT: ret + %1 = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 0) + %2 = tail call i1 @llvm.aarch64.sve.ptest.any.nxv16i1( %1, %1) + ret i1 %2 +} + +declare i1 @llvm.aarch64.sve.ptest.any.nxv16i1(, ) +declare @llvm.aarch64.sve.ptrue.nxv16i1(i32 %pattern)