[llvm] [AArch64] Sink NOT to be fold into BIC/ORN/EON (PR #176194)
Piotr Fusik via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 02:54:03 PST 2026
https://github.com/pfusik updated https://github.com/llvm/llvm-project/pull/176194
>From d64093835ee351bd9a6b0726dda73bb307a06e77 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Thu, 15 Jan 2026 15:34:49 +0100
Subject: [PATCH 1/4] [Aarch64][test] Sink NOT to be fold into BIC/ORN/EON
---
.../CodeGen/AArch64/logical-op-with-not.ll | 396 +++++++++++
.../AArch64/neon-bitwise-instructions.ll | 664 ++++++++++++++++++
2 files changed, 1060 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
index 3c4f06026a3cf..8db4ab6c8c4e9 100644
--- a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
+++ b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
@@ -320,3 +320,399 @@ define i64 @mvn_ror_i64(i64 %0) {
%5 = xor i64 %4, -1
ret i64 %5
}
+
+define void @array_and_not_i8(ptr %a, i8 %m) {
+; CHECK-LABEL: array_and_not_i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB26_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrb w10, [x0, x8]
+; CHECK-NEXT: and w10, w10, w9
+; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #1
+; CHECK-NEXT: cmp x8, #16
+; CHECK-NEXT: b.ne .LBB26_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i8 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i8, ptr %a, i64 %indvars.iv
+ %load = load i8, ptr %arrayidx, align 1
+ %and = and i8 %load, %not
+ store i8 %and, ptr %arrayidx, align 1
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_and_not_i16(ptr %a, i16 %m) {
+; CHECK-LABEL: array_and_not_i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB27_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrh w10, [x0, x8]
+; CHECK-NEXT: and w10, w10, w9
+; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #2
+; CHECK-NEXT: cmp x8, #32
+; CHECK-NEXT: b.ne .LBB27_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i16 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i16, ptr %a, i64 %indvars.iv
+ %load = load i16, ptr %arrayidx, align 2
+ %and = and i16 %load, %not
+ store i16 %and, ptr %arrayidx, align 2
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_and_not_i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_and_not_i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB28_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr w10, [x0, x8]
+; CHECK-NEXT: and w10, w10, w9
+; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #4
+; CHECK-NEXT: cmp x8, #64
+; CHECK-NEXT: b.ne .LBB28_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i32, ptr %a, i64 %indvars.iv
+ %load = load i32, ptr %arrayidx, align 4
+ %and = and i32 %load, %not
+ store i32 %and, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_and_not_i64(ptr %a, i64 %m) {
+; CHECK-LABEL: array_and_not_i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn x9, x1
+; CHECK-NEXT: .LBB29_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr x10, [x0, x8]
+; CHECK-NEXT: and x10, x10, x9
+; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #8
+; CHECK-NEXT: cmp x8, #128
+; CHECK-NEXT: b.ne .LBB29_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i64 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i64, ptr %a, i64 %indvars.iv
+ %load = load i64, ptr %arrayidx, align 8
+ %and = and i64 %load, %not
+ store i64 %and, ptr %arrayidx, align 8
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_or_not_i8(ptr %a, i8 %m) {
+; CHECK-LABEL: array_or_not_i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB30_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrb w10, [x0, x8]
+; CHECK-NEXT: orr w10, w10, w9
+; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #1
+; CHECK-NEXT: cmp x8, #16
+; CHECK-NEXT: b.ne .LBB30_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i8 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i8, ptr %a, i64 %indvars.iv
+ %load = load i8, ptr %arrayidx, align 1
+ %or = or i8 %load, %not
+ store i8 %or, ptr %arrayidx, align 1
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_or_not_i16(ptr %a, i16 %m) {
+; CHECK-LABEL: array_or_not_i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB31_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrh w10, [x0, x8]
+; CHECK-NEXT: orr w10, w10, w9
+; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #2
+; CHECK-NEXT: cmp x8, #32
+; CHECK-NEXT: b.ne .LBB31_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i16 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i16, ptr %a, i64 %indvars.iv
+ %load = load i16, ptr %arrayidx, align 2
+ %or = or i16 %load, %not
+ store i16 %or, ptr %arrayidx, align 2
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_or_not_i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_or_not_i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB32_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr w10, [x0, x8]
+; CHECK-NEXT: orr w10, w10, w9
+; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #4
+; CHECK-NEXT: cmp x8, #64
+; CHECK-NEXT: b.ne .LBB32_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i32, ptr %a, i64 %indvars.iv
+ %load = load i32, ptr %arrayidx, align 4
+ %or = or i32 %load, %not
+ store i32 %or, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_or_not_i64(ptr %a, i64 %m) {
+; CHECK-LABEL: array_or_not_i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn x9, x1
+; CHECK-NEXT: .LBB33_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr x10, [x0, x8]
+; CHECK-NEXT: orr x10, x10, x9
+; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #8
+; CHECK-NEXT: cmp x8, #128
+; CHECK-NEXT: b.ne .LBB33_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i64 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i64, ptr %a, i64 %indvars.iv
+ %load = load i64, ptr %arrayidx, align 8
+ %or = or i64 %load, %not
+ store i64 %or, ptr %arrayidx, align 8
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_xor_not_i8(ptr %a, i8 %m) {
+; CHECK-LABEL: array_xor_not_i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB34_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrb w10, [x0, x8]
+; CHECK-NEXT: eor w10, w10, w9
+; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #1
+; CHECK-NEXT: cmp x8, #16
+; CHECK-NEXT: b.ne .LBB34_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i8 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i8, ptr %a, i64 %indvars.iv
+ %load = load i8, ptr %arrayidx, align 1
+ %xor = xor i8 %load, %not
+ store i8 %xor, ptr %arrayidx, align 1
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_xor_not_i16(ptr %a, i16 %m) {
+; CHECK-LABEL: array_xor_not_i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB35_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldrh w10, [x0, x8]
+; CHECK-NEXT: eor w10, w10, w9
+; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #2
+; CHECK-NEXT: cmp x8, #32
+; CHECK-NEXT: b.ne .LBB35_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i16 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i16, ptr %a, i64 %indvars.iv
+ %load = load i16, ptr %arrayidx, align 2
+ %xor = xor i16 %load, %not
+ store i16 %xor, ptr %arrayidx, align 2
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_xor_not_i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_xor_not_i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
+; CHECK-NEXT: .LBB36_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr w10, [x0, x8]
+; CHECK-NEXT: eor w10, w10, w9
+; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #4
+; CHECK-NEXT: cmp x8, #64
+; CHECK-NEXT: b.ne .LBB36_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i32, ptr %a, i64 %indvars.iv
+ %load = load i32, ptr %arrayidx, align 4
+ %xor = xor i32 %load, %not
+ store i32 %xor, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+define void @array_xor_not_i64(ptr %a, i64 %m) {
+; CHECK-LABEL: array_xor_not_i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn x9, x1
+; CHECK-NEXT: .LBB37_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr x10, [x0, x8]
+; CHECK-NEXT: eor x10, x10, x9
+; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: add x8, x8, #8
+; CHECK-NEXT: cmp x8, #128
+; CHECK-NEXT: b.ne .LBB37_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i64 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i64, ptr %a, i64 %indvars.iv
+ %load = load i64, ptr %arrayidx, align 8
+ %xor = xor i64 %load, %not
+ store i64 %xor, ptr %arrayidx, align 8
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 16
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
diff --git a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
index ac7c6c00e0533..9c936161e5b34 100644
--- a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
@@ -3388,3 +3388,667 @@ define <2 x i64> @or_dup_not_v2i64(<2 x i64> %a, i64 %m) {
%or = or <2 x i64> %a, %shuffle
ret <2 x i64> %or
}
+
+define void @array_and_not_v16i8(ptr %a, <16 x i8> %m) {
+; CHECK-SD-LABEL: array_and_not_v16i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB211_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #256
+; CHECK-SD-NEXT: b.ne .LBB211_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_v16i8:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB211_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #256
+; CHECK-GI-NEXT: b.ne .LBB211_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <16 x i8> %m, splat (i8 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i8, ptr %a, i64 %index
+ %wide.load = load <16 x i8>, ptr %gep, align 1
+ %1 = and <16 x i8> %wide.load, %not
+ store <16 x i8> %1, ptr %gep, align 1
+ %index.next = add nuw i64 %index, 16
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_v8i16(ptr %a, <8 x i16> %m) {
+; CHECK-SD-LABEL: array_and_not_v8i16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB212_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #512
+; CHECK-SD-NEXT: b.ne .LBB212_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_v8i16:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB212_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #512
+; CHECK-GI-NEXT: b.ne .LBB212_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <8 x i16> %m, splat (i16 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i16, ptr %a, i64 %index
+ %wide.load = load <8 x i16>, ptr %gep, align 2
+ %1 = and <8 x i16> %wide.load, %not
+ store <8 x i16> %1, ptr %gep, align 2
+ %index.next = add nuw i64 %index, 8
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_v4i32(ptr %a, <4 x i32> %m) {
+; CHECK-SD-LABEL: array_and_not_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB213_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #1024
+; CHECK-SD-NEXT: b.ne .LBB213_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_v4i32:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB213_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #1024
+; CHECK-GI-NEXT: b.ne .LBB213_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <4 x i32> %m, splat (i32 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i32, ptr %a, i64 %index
+ %wide.load = load <4 x i32>, ptr %gep, align 4
+ %1 = and <4 x i32> %wide.load, %not
+ store <4 x i32> %1, ptr %gep, align 4
+ %index.next = add nuw i64 %index, 4
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_v2i64(ptr %a, <2 x i64> %m) {
+; CHECK-SD-LABEL: array_and_not_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB214_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #2048
+; CHECK-SD-NEXT: b.ne .LBB214_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_v2i64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB214_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #2048
+; CHECK-GI-NEXT: b.ne .LBB214_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <2 x i64> %m, splat (i64 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i64, ptr %a, i64 %index
+ %wide.load = load <2 x i64>, ptr %gep, align 8
+ %1 = and <2 x i64> %wide.load, %not
+ store <2 x i64> %1, ptr %gep, align 8
+ %index.next = add nuw i64 %index, 2
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_v16i8(ptr %a, <16 x i8> %m) {
+; CHECK-SD-LABEL: array_or_not_v16i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB215_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #256
+; CHECK-SD-NEXT: b.ne .LBB215_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_v16i8:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB215_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #256
+; CHECK-GI-NEXT: b.ne .LBB215_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <16 x i8> %m, splat (i8 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i8, ptr %a, i64 %index
+ %wide.load = load <16 x i8>, ptr %gep, align 1
+ %1 = or <16 x i8> %wide.load, %not
+ store <16 x i8> %1, ptr %gep, align 1
+ %index.next = add nuw i64 %index, 16
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_v8i16(ptr %a, <8 x i16> %m) {
+; CHECK-SD-LABEL: array_or_not_v8i16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB216_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #512
+; CHECK-SD-NEXT: b.ne .LBB216_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_v8i16:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB216_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #512
+; CHECK-GI-NEXT: b.ne .LBB216_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <8 x i16> %m, splat (i16 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i16, ptr %a, i64 %index
+ %wide.load = load <8 x i16>, ptr %gep, align 2
+ %1 = or <8 x i16> %wide.load, %not
+ store <8 x i16> %1, ptr %gep, align 2
+ %index.next = add nuw i64 %index, 8
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_v4i32(ptr %a, <4 x i32> %m) {
+; CHECK-SD-LABEL: array_or_not_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB217_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #1024
+; CHECK-SD-NEXT: b.ne .LBB217_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_v4i32:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB217_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #1024
+; CHECK-GI-NEXT: b.ne .LBB217_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <4 x i32> %m, splat (i32 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i32, ptr %a, i64 %index
+ %wide.load = load <4 x i32>, ptr %gep, align 4
+ %1 = or <4 x i32> %wide.load, %not
+ store <4 x i32> %1, ptr %gep, align 4
+ %index.next = add nuw i64 %index, 4
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_v2i64(ptr %a, <2 x i64> %m) {
+; CHECK-SD-LABEL: array_or_not_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: mvn v0.16b, v0.16b
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB218_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #2048
+; CHECK-SD-NEXT: b.ne .LBB218_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_v2i64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB218_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #2048
+; CHECK-GI-NEXT: b.ne .LBB218_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
+entry:
+ %not = xor <2 x i64> %m, splat (i64 -1)
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i64, ptr %a, i64 %index
+ %wide.load = load <2 x i64>, ptr %gep, align 8
+ %1 = or <2 x i64> %wide.load, %not
+ store <2 x i64> %1, ptr %gep, align 8
+ %index.next = add nuw i64 %index, 2
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_dup_v16i8(ptr %a, i8 %m) {
+; CHECK-LABEL: array_and_not_dup_v16i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.16b, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB219_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #256
+; CHECK-NEXT: b.ne .LBB219_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i8 %m, -1
+ %broadcast.splatinsert = insertelement <16 x i8> poison, i8 %not, i64 0
+ %broadcast.splat = shufflevector <16 x i8> %broadcast.splatinsert, <16 x i8> poison, <16 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i8, ptr %a, i64 %index
+ %wide.load = load <16 x i8>, ptr %gep, align 1
+ %1 = and <16 x i8> %wide.load, %broadcast.splat
+ store <16 x i8> %1, ptr %gep, align 1
+ %index.next = add nuw i64 %index, 16
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_dup_v8i16(ptr %a, i16 %m) {
+; CHECK-LABEL: array_and_not_dup_v8i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.8h, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB220_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #512
+; CHECK-NEXT: b.ne .LBB220_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i16 %m, -1
+ %broadcast.splatinsert = insertelement <8 x i16> poison, i16 %not, i64 0
+ %broadcast.splat = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i16, ptr %a, i64 %index
+ %wide.load = load <8 x i16>, ptr %gep, align 2
+ %1 = and <8 x i16> %wide.load, %broadcast.splat
+ store <8 x i16> %1, ptr %gep, align 2
+ %index.next = add nuw i64 %index, 8
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_dup_v4i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_and_not_dup_v4i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.4s, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB221_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #1024
+; CHECK-NEXT: b.ne .LBB221_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %not, i64 0
+ %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i32, ptr %a, i64 %index
+ %wide.load = load <4 x i32>, ptr %gep, align 4
+ %1 = and <4 x i32> %wide.load, %broadcast.splat
+ store <4 x i32> %1, ptr %gep, align 4
+ %index.next = add nuw i64 %index, 4
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_and_not_dup_v2i64(ptr %a, i64 %m) {
+; CHECK-LABEL: array_and_not_dup_v2i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn x8, x1
+; CHECK-NEXT: dup v0.2d, x8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB222_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #2048
+; CHECK-NEXT: b.ne .LBB222_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i64 %m, -1
+ %broadcast.splatinsert = insertelement <2 x i64> poison, i64 %not, i64 0
+ %broadcast.splat = shufflevector <2 x i64> %broadcast.splatinsert, <2 x i64> poison, <2 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i64, ptr %a, i64 %index
+ %wide.load = load <2 x i64>, ptr %gep, align 8
+ %1 = and <2 x i64> %wide.load, %broadcast.splat
+ store <2 x i64> %1, ptr %gep, align 8
+ %index.next = add nuw i64 %index, 2
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_dup_v16i8(ptr %a, i8 %m) {
+; CHECK-LABEL: array_or_not_dup_v16i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.16b, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB223_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #256
+; CHECK-NEXT: b.ne .LBB223_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i8 %m, -1
+ %broadcast.splatinsert = insertelement <16 x i8> poison, i8 %not, i64 0
+ %broadcast.splat = shufflevector <16 x i8> %broadcast.splatinsert, <16 x i8> poison, <16 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i8, ptr %a, i64 %index
+ %wide.load = load <16 x i8>, ptr %gep, align 1
+ %1 = or <16 x i8> %wide.load, %broadcast.splat
+ store <16 x i8> %1, ptr %gep, align 1
+ %index.next = add nuw i64 %index, 16
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_dup_v8i16(ptr %a, i16 %m) {
+; CHECK-LABEL: array_or_not_dup_v8i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.8h, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB224_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #512
+; CHECK-NEXT: b.ne .LBB224_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i16 %m, -1
+ %broadcast.splatinsert = insertelement <8 x i16> poison, i16 %not, i64 0
+ %broadcast.splat = shufflevector <8 x i16> %broadcast.splatinsert, <8 x i16> poison, <8 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i16, ptr %a, i64 %index
+ %wide.load = load <8 x i16>, ptr %gep, align 2
+ %1 = or <8 x i16> %wide.load, %broadcast.splat
+ store <8 x i16> %1, ptr %gep, align 2
+ %index.next = add nuw i64 %index, 8
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_dup_v4i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_or_not_dup_v4i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn w8, w1
+; CHECK-NEXT: dup v0.4s, w8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB225_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #1024
+; CHECK-NEXT: b.ne .LBB225_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %not, i64 0
+ %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i32, ptr %a, i64 %index
+ %wide.load = load <4 x i32>, ptr %gep, align 4
+ %1 = or <4 x i32> %wide.load, %broadcast.splat
+ store <4 x i32> %1, ptr %gep, align 4
+ %index.next = add nuw i64 %index, 4
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
+
+define void @array_or_not_dup_v2i64(ptr %a, i64 %m) {
+; CHECK-LABEL: array_or_not_dup_v2i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mvn x8, x1
+; CHECK-NEXT: dup v0.2d, x8
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB226_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #2048
+; CHECK-NEXT: b.ne .LBB226_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i64 %m, -1
+ %broadcast.splatinsert = insertelement <2 x i64> poison, i64 %not, i64 0
+ %broadcast.splat = shufflevector <2 x i64> %broadcast.splatinsert, <2 x i64> poison, <2 x i32> zeroinitializer
+ br label %vector.body
+
+vector.body:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ]
+ %gep = getelementptr inbounds nuw i64, ptr %a, i64 %index
+ %wide.load = load <2 x i64>, ptr %gep, align 8
+ %1 = or <2 x i64> %wide.load, %broadcast.splat
+ store <2 x i64> %1, ptr %gep, align 8
+ %index.next = add nuw i64 %index, 2
+ %2 = icmp eq i64 %index.next, 256
+ br i1 %2, label %for.cond.cleanup, label %vector.body
+
+for.cond.cleanup:
+ ret void
+}
>From aeb44a98a427fe4b744de5fe9ed1a4e5cbb21cde Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Thu, 15 Jan 2026 15:36:34 +0100
Subject: [PATCH 2/4] [Aarch64] Sink NOT to be fold into BIC/ORN/EON
Undoes a negation being hoisted out of a loop, so that if can be fold
into an inverted bitwise operation in the loop.
Implements #108840 on AArch64
---
.../AArch64/AArch64TargetTransformInfo.cpp | 26 +-
.../CodeGen/AArch64/logical-op-with-not.ll | 84 +--
.../AArch64/neon-bitwise-instructions.ll | 688 +++++++++---------
3 files changed, 405 insertions(+), 393 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index b96d251a9c4d9..529846f5edbd8 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -6818,7 +6818,31 @@ bool AArch64TTIImpl::isProfitableToSinkOperands(
Ops.push_back(&I->getOperandUse(1));
}
break;
-
+ case Instruction::Xor:
+ if (I->getType()->isVectorTy() && ST->hasNEON())
+ break; // NEON has no eon instruction
+ [[fallthrough]];
+ case Instruction::And:
+ case Instruction::Or:
+ for (auto &Op : I->operands()) {
+ // (and/or/xor X, (not Y)) -> (bic/orn/eon X, Y)
+ if (match(Op.get(), m_Not(m_Value()))) {
+ Ops.push_back(&Op);
+ return true;
+ }
+ // (and/or/xor X, (splat (not Y))) -> (bic/orn/eon X, (splat Y))
+ if (match(Op.get(),
+ m_Shuffle(m_InsertElt(m_Value(), m_Not(m_Value()), m_ZeroInt()),
+ m_Value(), m_ZeroMask()))) {
+ Use &InsertElt = cast<Instruction>(Op)->getOperandUse(0);
+ Use &Not = cast<Instruction>(InsertElt)->getOperandUse(1);
+ Ops.push_back(&Not);
+ Ops.push_back(&InsertElt);
+ Ops.push_back(&Op);
+ return true;
+ }
+ }
+ break;
default:
break;
}
diff --git a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
index 8db4ab6c8c4e9..4b35f92e6c660 100644
--- a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
+++ b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
@@ -325,12 +325,11 @@ define void @array_and_not_i8(ptr %a, i8 %m) {
; CHECK-LABEL: array_and_not_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB26_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrb w10, [x0, x8]
-; CHECK-NEXT: and w10, w10, w9
-; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: ldrb w9, [x0, x8]
+; CHECK-NEXT: bic w9, w9, w1
+; CHECK-NEXT: strb w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #1
; CHECK-NEXT: cmp x8, #16
; CHECK-NEXT: b.ne .LBB26_1
@@ -358,12 +357,11 @@ define void @array_and_not_i16(ptr %a, i16 %m) {
; CHECK-LABEL: array_and_not_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB27_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrh w10, [x0, x8]
-; CHECK-NEXT: and w10, w10, w9
-; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: ldrh w9, [x0, x8]
+; CHECK-NEXT: bic w9, w9, w1
+; CHECK-NEXT: strh w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #2
; CHECK-NEXT: cmp x8, #32
; CHECK-NEXT: b.ne .LBB27_1
@@ -391,12 +389,11 @@ define void @array_and_not_i32(ptr %a, i32 %m) {
; CHECK-LABEL: array_and_not_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB28_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr w10, [x0, x8]
-; CHECK-NEXT: and w10, w10, w9
-; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: ldr w9, [x0, x8]
+; CHECK-NEXT: bic w9, w9, w1
+; CHECK-NEXT: str w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #4
; CHECK-NEXT: cmp x8, #64
; CHECK-NEXT: b.ne .LBB28_1
@@ -424,12 +421,11 @@ define void @array_and_not_i64(ptr %a, i64 %m) {
; CHECK-LABEL: array_and_not_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: .LBB29_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr x10, [x0, x8]
-; CHECK-NEXT: and x10, x10, x9
-; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: ldr x9, [x0, x8]
+; CHECK-NEXT: bic x9, x9, x1
+; CHECK-NEXT: str x9, [x0, x8]
; CHECK-NEXT: add x8, x8, #8
; CHECK-NEXT: cmp x8, #128
; CHECK-NEXT: b.ne .LBB29_1
@@ -457,12 +453,11 @@ define void @array_or_not_i8(ptr %a, i8 %m) {
; CHECK-LABEL: array_or_not_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB30_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrb w10, [x0, x8]
-; CHECK-NEXT: orr w10, w10, w9
-; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: ldrb w9, [x0, x8]
+; CHECK-NEXT: orn w9, w9, w1
+; CHECK-NEXT: strb w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #1
; CHECK-NEXT: cmp x8, #16
; CHECK-NEXT: b.ne .LBB30_1
@@ -490,12 +485,11 @@ define void @array_or_not_i16(ptr %a, i16 %m) {
; CHECK-LABEL: array_or_not_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB31_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrh w10, [x0, x8]
-; CHECK-NEXT: orr w10, w10, w9
-; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: ldrh w9, [x0, x8]
+; CHECK-NEXT: orn w9, w9, w1
+; CHECK-NEXT: strh w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #2
; CHECK-NEXT: cmp x8, #32
; CHECK-NEXT: b.ne .LBB31_1
@@ -523,12 +517,11 @@ define void @array_or_not_i32(ptr %a, i32 %m) {
; CHECK-LABEL: array_or_not_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB32_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr w10, [x0, x8]
-; CHECK-NEXT: orr w10, w10, w9
-; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: ldr w9, [x0, x8]
+; CHECK-NEXT: orn w9, w9, w1
+; CHECK-NEXT: str w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #4
; CHECK-NEXT: cmp x8, #64
; CHECK-NEXT: b.ne .LBB32_1
@@ -556,12 +549,11 @@ define void @array_or_not_i64(ptr %a, i64 %m) {
; CHECK-LABEL: array_or_not_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: .LBB33_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr x10, [x0, x8]
-; CHECK-NEXT: orr x10, x10, x9
-; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: ldr x9, [x0, x8]
+; CHECK-NEXT: orn x9, x9, x1
+; CHECK-NEXT: str x9, [x0, x8]
; CHECK-NEXT: add x8, x8, #8
; CHECK-NEXT: cmp x8, #128
; CHECK-NEXT: b.ne .LBB33_1
@@ -589,12 +581,11 @@ define void @array_xor_not_i8(ptr %a, i8 %m) {
; CHECK-LABEL: array_xor_not_i8:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB34_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrb w10, [x0, x8]
-; CHECK-NEXT: eor w10, w10, w9
-; CHECK-NEXT: strb w10, [x0, x8]
+; CHECK-NEXT: ldrb w9, [x0, x8]
+; CHECK-NEXT: eon w9, w1, w9
+; CHECK-NEXT: strb w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #1
; CHECK-NEXT: cmp x8, #16
; CHECK-NEXT: b.ne .LBB34_1
@@ -622,12 +613,11 @@ define void @array_xor_not_i16(ptr %a, i16 %m) {
; CHECK-LABEL: array_xor_not_i16:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB35_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldrh w10, [x0, x8]
-; CHECK-NEXT: eor w10, w10, w9
-; CHECK-NEXT: strh w10, [x0, x8]
+; CHECK-NEXT: ldrh w9, [x0, x8]
+; CHECK-NEXT: eon w9, w1, w9
+; CHECK-NEXT: strh w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #2
; CHECK-NEXT: cmp x8, #32
; CHECK-NEXT: b.ne .LBB35_1
@@ -655,12 +645,11 @@ define void @array_xor_not_i32(ptr %a, i32 %m) {
; CHECK-LABEL: array_xor_not_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB36_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr w10, [x0, x8]
-; CHECK-NEXT: eor w10, w10, w9
-; CHECK-NEXT: str w10, [x0, x8]
+; CHECK-NEXT: ldr w9, [x0, x8]
+; CHECK-NEXT: eon w9, w1, w9
+; CHECK-NEXT: str w9, [x0, x8]
; CHECK-NEXT: add x8, x8, #4
; CHECK-NEXT: cmp x8, #64
; CHECK-NEXT: b.ne .LBB36_1
@@ -688,12 +677,11 @@ define void @array_xor_not_i64(ptr %a, i64 %m) {
; CHECK-LABEL: array_xor_not_i64:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: mvn x9, x1
; CHECK-NEXT: .LBB37_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr x10, [x0, x8]
-; CHECK-NEXT: eor x10, x10, x9
-; CHECK-NEXT: str x10, [x0, x8]
+; CHECK-NEXT: ldr x9, [x0, x8]
+; CHECK-NEXT: eon x9, x1, x9
+; CHECK-NEXT: str x9, [x0, x8]
; CHECK-NEXT: add x8, x8, #8
; CHECK-NEXT: cmp x8, #128
; CHECK-NEXT: b.ne .LBB37_1
diff --git a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
index 9c936161e5b34..63fb1296f66be 100644
--- a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
@@ -3390,34 +3390,19 @@ define <2 x i64> @or_dup_not_v2i64(<2 x i64> %a, i64 %m) {
}
define void @array_and_not_v16i8(ptr %a, <16 x i8> %m) {
-; CHECK-SD-LABEL: array_and_not_v16i8:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB211_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #256
-; CHECK-SD-NEXT: b.ne .LBB211_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_and_not_v16i8:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB211_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #256
-; CHECK-GI-NEXT: b.ne .LBB211_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_and_not_v16i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB211_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #256
+; CHECK-NEXT: b.ne .LBB211_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <16 x i8> %m, splat (i8 -1)
br label %vector.body
@@ -3437,34 +3422,19 @@ for.cond.cleanup:
}
define void @array_and_not_v8i16(ptr %a, <8 x i16> %m) {
-; CHECK-SD-LABEL: array_and_not_v8i16:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB212_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #512
-; CHECK-SD-NEXT: b.ne .LBB212_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_and_not_v8i16:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB212_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #512
-; CHECK-GI-NEXT: b.ne .LBB212_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_and_not_v8i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB212_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #512
+; CHECK-NEXT: b.ne .LBB212_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <8 x i16> %m, splat (i16 -1)
br label %vector.body
@@ -3484,34 +3454,19 @@ for.cond.cleanup:
}
define void @array_and_not_v4i32(ptr %a, <4 x i32> %m) {
-; CHECK-SD-LABEL: array_and_not_v4i32:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB213_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #1024
-; CHECK-SD-NEXT: b.ne .LBB213_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_and_not_v4i32:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB213_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #1024
-; CHECK-GI-NEXT: b.ne .LBB213_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_and_not_v4i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB213_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #1024
+; CHECK-NEXT: b.ne .LBB213_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <4 x i32> %m, splat (i32 -1)
br label %vector.body
@@ -3531,34 +3486,19 @@ for.cond.cleanup:
}
define void @array_and_not_v2i64(ptr %a, <2 x i64> %m) {
-; CHECK-SD-LABEL: array_and_not_v2i64:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB214_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #2048
-; CHECK-SD-NEXT: b.ne .LBB214_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_and_not_v2i64:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB214_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: bic v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #2048
-; CHECK-GI-NEXT: b.ne .LBB214_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_and_not_v2i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB214_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #2048
+; CHECK-NEXT: b.ne .LBB214_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <2 x i64> %m, splat (i64 -1)
br label %vector.body
@@ -3578,34 +3518,19 @@ for.cond.cleanup:
}
define void @array_or_not_v16i8(ptr %a, <16 x i8> %m) {
-; CHECK-SD-LABEL: array_or_not_v16i8:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB215_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #256
-; CHECK-SD-NEXT: b.ne .LBB215_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_or_not_v16i8:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB215_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #256
-; CHECK-GI-NEXT: b.ne .LBB215_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_or_not_v16i8:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB215_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #256
+; CHECK-NEXT: b.ne .LBB215_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <16 x i8> %m, splat (i8 -1)
br label %vector.body
@@ -3625,34 +3550,19 @@ for.cond.cleanup:
}
define void @array_or_not_v8i16(ptr %a, <8 x i16> %m) {
-; CHECK-SD-LABEL: array_or_not_v8i16:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB216_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #512
-; CHECK-SD-NEXT: b.ne .LBB216_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_or_not_v8i16:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB216_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #512
-; CHECK-GI-NEXT: b.ne .LBB216_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_or_not_v8i16:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB216_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #512
+; CHECK-NEXT: b.ne .LBB216_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <8 x i16> %m, splat (i16 -1)
br label %vector.body
@@ -3672,34 +3582,19 @@ for.cond.cleanup:
}
define void @array_or_not_v4i32(ptr %a, <4 x i32> %m) {
-; CHECK-SD-LABEL: array_or_not_v4i32:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB217_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #1024
-; CHECK-SD-NEXT: b.ne .LBB217_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_or_not_v4i32:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB217_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #1024
-; CHECK-GI-NEXT: b.ne .LBB217_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_or_not_v4i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB217_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #1024
+; CHECK-NEXT: b.ne .LBB217_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <4 x i32> %m, splat (i32 -1)
br label %vector.body
@@ -3719,34 +3614,19 @@ for.cond.cleanup:
}
define void @array_or_not_v2i64(ptr %a, <2 x i64> %m) {
-; CHECK-SD-LABEL: array_or_not_v2i64:
-; CHECK-SD: // %bb.0: // %entry
-; CHECK-SD-NEXT: mvn v0.16b, v0.16b
-; CHECK-SD-NEXT: mov x8, xzr
-; CHECK-SD-NEXT: .LBB218_1: // %vector.body
-; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-SD-NEXT: ldr q1, [x0, x8]
-; CHECK-SD-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-SD-NEXT: str q1, [x0, x8]
-; CHECK-SD-NEXT: add x8, x8, #16
-; CHECK-SD-NEXT: cmp x8, #2048
-; CHECK-SD-NEXT: b.ne .LBB218_1
-; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: array_or_not_v2i64:
-; CHECK-GI: // %bb.0: // %entry
-; CHECK-GI-NEXT: mov x8, xzr
-; CHECK-GI-NEXT: .LBB218_1: // %vector.body
-; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-GI-NEXT: ldr q1, [x0, x8]
-; CHECK-GI-NEXT: orn v1.16b, v1.16b, v0.16b
-; CHECK-GI-NEXT: str q1, [x0, x8]
-; CHECK-GI-NEXT: add x8, x8, #16
-; CHECK-GI-NEXT: cmp x8, #2048
-; CHECK-GI-NEXT: b.ne .LBB218_1
-; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: array_or_not_v2i64:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB218_1: // %vector.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr q1, [x0, x8]
+; CHECK-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-NEXT: str q1, [x0, x8]
+; CHECK-NEXT: add x8, x8, #16
+; CHECK-NEXT: cmp x8, #2048
+; CHECK-NEXT: b.ne .LBB218_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
entry:
%not = xor <2 x i64> %m, splat (i64 -1)
br label %vector.body
@@ -3766,21 +3646,36 @@ for.cond.cleanup:
}
define void @array_and_not_dup_v16i8(ptr %a, i8 %m) {
-; CHECK-LABEL: array_and_not_dup_v16i8:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.16b, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB219_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #256
-; CHECK-NEXT: b.ne .LBB219_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_and_not_dup_v16i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.16b, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB219_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #256
+; CHECK-SD-NEXT: b.ne .LBB219_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_dup_v16i8:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.16b, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB219_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #256
+; CHECK-GI-NEXT: b.ne .LBB219_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i8 %m, -1
%broadcast.splatinsert = insertelement <16 x i8> poison, i8 %not, i64 0
@@ -3802,21 +3697,36 @@ for.cond.cleanup:
}
define void @array_and_not_dup_v8i16(ptr %a, i16 %m) {
-; CHECK-LABEL: array_and_not_dup_v8i16:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.8h, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB220_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #512
-; CHECK-NEXT: b.ne .LBB220_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_and_not_dup_v8i16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.8h, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB220_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #512
+; CHECK-SD-NEXT: b.ne .LBB220_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_dup_v8i16:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.8h, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB220_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #512
+; CHECK-GI-NEXT: b.ne .LBB220_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i16 %m, -1
%broadcast.splatinsert = insertelement <8 x i16> poison, i16 %not, i64 0
@@ -3838,21 +3748,36 @@ for.cond.cleanup:
}
define void @array_and_not_dup_v4i32(ptr %a, i32 %m) {
-; CHECK-LABEL: array_and_not_dup_v4i32:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.4s, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB221_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #1024
-; CHECK-NEXT: b.ne .LBB221_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_and_not_dup_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.4s, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB221_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #1024
+; CHECK-SD-NEXT: b.ne .LBB221_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_dup_v4i32:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.4s, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB221_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #1024
+; CHECK-GI-NEXT: b.ne .LBB221_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i32 %m, -1
%broadcast.splatinsert = insertelement <4 x i32> poison, i32 %not, i64 0
@@ -3874,21 +3799,36 @@ for.cond.cleanup:
}
define void @array_and_not_dup_v2i64(ptr %a, i64 %m) {
-; CHECK-LABEL: array_and_not_dup_v2i64:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn x8, x1
-; CHECK-NEXT: dup v0.2d, x8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB222_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: and v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #2048
-; CHECK-NEXT: b.ne .LBB222_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_and_not_dup_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.2d, x1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB222_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: bic v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #2048
+; CHECK-SD-NEXT: b.ne .LBB222_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_and_not_dup_v2i64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn x8, x1
+; CHECK-GI-NEXT: dup v0.2d, x8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB222_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: and v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #2048
+; CHECK-GI-NEXT: b.ne .LBB222_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i64 %m, -1
%broadcast.splatinsert = insertelement <2 x i64> poison, i64 %not, i64 0
@@ -3910,21 +3850,36 @@ for.cond.cleanup:
}
define void @array_or_not_dup_v16i8(ptr %a, i8 %m) {
-; CHECK-LABEL: array_or_not_dup_v16i8:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.16b, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB223_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #256
-; CHECK-NEXT: b.ne .LBB223_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_or_not_dup_v16i8:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.16b, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB223_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #256
+; CHECK-SD-NEXT: b.ne .LBB223_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_dup_v16i8:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.16b, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB223_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #256
+; CHECK-GI-NEXT: b.ne .LBB223_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i8 %m, -1
%broadcast.splatinsert = insertelement <16 x i8> poison, i8 %not, i64 0
@@ -3946,21 +3901,36 @@ for.cond.cleanup:
}
define void @array_or_not_dup_v8i16(ptr %a, i16 %m) {
-; CHECK-LABEL: array_or_not_dup_v8i16:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.8h, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB224_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #512
-; CHECK-NEXT: b.ne .LBB224_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_or_not_dup_v8i16:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.8h, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB224_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #512
+; CHECK-SD-NEXT: b.ne .LBB224_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_dup_v8i16:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.8h, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB224_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #512
+; CHECK-GI-NEXT: b.ne .LBB224_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i16 %m, -1
%broadcast.splatinsert = insertelement <8 x i16> poison, i16 %not, i64 0
@@ -3982,21 +3952,36 @@ for.cond.cleanup:
}
define void @array_or_not_dup_v4i32(ptr %a, i32 %m) {
-; CHECK-LABEL: array_or_not_dup_v4i32:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn w8, w1
-; CHECK-NEXT: dup v0.4s, w8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB225_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #1024
-; CHECK-NEXT: b.ne .LBB225_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_or_not_dup_v4i32:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.4s, w1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB225_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #1024
+; CHECK-SD-NEXT: b.ne .LBB225_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_dup_v4i32:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn w8, w1
+; CHECK-GI-NEXT: dup v0.4s, w8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB225_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #1024
+; CHECK-GI-NEXT: b.ne .LBB225_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i32 %m, -1
%broadcast.splatinsert = insertelement <4 x i32> poison, i32 %not, i64 0
@@ -4018,21 +4003,36 @@ for.cond.cleanup:
}
define void @array_or_not_dup_v2i64(ptr %a, i64 %m) {
-; CHECK-LABEL: array_or_not_dup_v2i64:
-; CHECK: // %bb.0: // %entry
-; CHECK-NEXT: mvn x8, x1
-; CHECK-NEXT: dup v0.2d, x8
-; CHECK-NEXT: mov x8, xzr
-; CHECK-NEXT: .LBB226_1: // %vector.body
-; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr q1, [x0, x8]
-; CHECK-NEXT: orr v1.16b, v1.16b, v0.16b
-; CHECK-NEXT: str q1, [x0, x8]
-; CHECK-NEXT: add x8, x8, #16
-; CHECK-NEXT: cmp x8, #2048
-; CHECK-NEXT: b.ne .LBB226_1
-; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
-; CHECK-NEXT: ret
+; CHECK-SD-LABEL: array_or_not_dup_v2i64:
+; CHECK-SD: // %bb.0: // %entry
+; CHECK-SD-NEXT: dup v0.2d, x1
+; CHECK-SD-NEXT: mov x8, xzr
+; CHECK-SD-NEXT: .LBB226_1: // %vector.body
+; CHECK-SD-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-SD-NEXT: ldr q1, [x0, x8]
+; CHECK-SD-NEXT: orn v1.16b, v1.16b, v0.16b
+; CHECK-SD-NEXT: str q1, [x0, x8]
+; CHECK-SD-NEXT: add x8, x8, #16
+; CHECK-SD-NEXT: cmp x8, #2048
+; CHECK-SD-NEXT: b.ne .LBB226_1
+; CHECK-SD-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: array_or_not_dup_v2i64:
+; CHECK-GI: // %bb.0: // %entry
+; CHECK-GI-NEXT: mvn x8, x1
+; CHECK-GI-NEXT: dup v0.2d, x8
+; CHECK-GI-NEXT: mov x8, xzr
+; CHECK-GI-NEXT: .LBB226_1: // %vector.body
+; CHECK-GI-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-GI-NEXT: ldr q1, [x0, x8]
+; CHECK-GI-NEXT: orr v1.16b, v1.16b, v0.16b
+; CHECK-GI-NEXT: str q1, [x0, x8]
+; CHECK-GI-NEXT: add x8, x8, #16
+; CHECK-GI-NEXT: cmp x8, #2048
+; CHECK-GI-NEXT: b.ne .LBB226_1
+; CHECK-GI-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-GI-NEXT: ret
entry:
%not = xor i64 %m, -1
%broadcast.splatinsert = insertelement <2 x i64> poison, i64 %not, i64 0
>From dee61fa844e004a701c030323fa4d20e23aa1063 Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Thu, 15 Jan 2026 16:39:37 +0100
Subject: [PATCH 3/4] [AArch64][test] Prefer folding a shift to NOT
---
.../CodeGen/AArch64/logical-op-with-not.ll | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
index 4b35f92e6c660..375eab5ae78bb 100644
--- a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
+++ b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
@@ -704,3 +704,37 @@ for.body:
%exitcond.not = icmp eq i64 %indvars.iv.next, 16
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
}
+
+define void @array_and_lsl2_not_i32(ptr %a, i32 %m) {
+; CHECK-LABEL: array_and_lsl2_not_i32:
+; CHECK: // %bb.0: // %entry
+; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: .LBB38_1: // %for.body
+; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
+; CHECK-NEXT: ldr w9, [x0, x8]
+; CHECK-NEXT: lsl w9, w9, #2
+; CHECK-NEXT: bic w9, w9, w1
+; CHECK-NEXT: str w9, [x0, x8]
+; CHECK-NEXT: add x8, x8, #4
+; CHECK-NEXT: cmp x8, #1024
+; CHECK-NEXT: b.ne .LBB38_1
+; CHECK-NEXT: // %bb.2: // %for.cond.cleanup
+; CHECK-NEXT: ret
+entry:
+ %not = xor i32 %m, -1
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds nuw i32, ptr %a, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %shl = shl i32 %0, 2
+ %and = and i32 %shl, %not
+ store i32 %and, ptr %arrayidx, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 256
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
>From 9d746a716d72f91afd9f17a6a48559e3dfae4a9a Mon Sep 17 00:00:00 2001
From: Piotr Fusik <p.fusik at samsung.com>
Date: Thu, 15 Jan 2026 16:57:56 +0100
Subject: [PATCH 4/4] [AArch64] Prefer folding a shift to NOT
---
llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp | 5 +++++
llvm/test/CodeGen/AArch64/logical-op-with-not.ll | 8 ++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 529846f5edbd8..8148cac8fe107 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -6824,6 +6824,11 @@ bool AArch64TTIImpl::isProfitableToSinkOperands(
[[fallthrough]];
case Instruction::And:
case Instruction::Or:
+ // Shift can be fold into scalar AND/ORR/EOR,
+ // but not the non-negated operand of BIC/ORN/EON.
+ if (!(I->getType()->isVectorTy() && ST->hasNEON()) &&
+ match(I, m_c_BinOp(m_Shift(m_Value(), m_ConstantInt()), m_Value())))
+ break;
for (auto &Op : I->operands()) {
// (and/or/xor X, (not Y)) -> (bic/orn/eon X, Y)
if (match(Op.get(), m_Not(m_Value()))) {
diff --git a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
index 375eab5ae78bb..2f5610a18aa9c 100644
--- a/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
+++ b/llvm/test/CodeGen/AArch64/logical-op-with-not.ll
@@ -709,12 +709,12 @@ define void @array_and_lsl2_not_i32(ptr %a, i32 %m) {
; CHECK-LABEL: array_and_lsl2_not_i32:
; CHECK: // %bb.0: // %entry
; CHECK-NEXT: mov x8, xzr
+; CHECK-NEXT: mvn w9, w1
; CHECK-NEXT: .LBB38_1: // %for.body
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
-; CHECK-NEXT: ldr w9, [x0, x8]
-; CHECK-NEXT: lsl w9, w9, #2
-; CHECK-NEXT: bic w9, w9, w1
-; CHECK-NEXT: str w9, [x0, x8]
+; CHECK-NEXT: ldr w10, [x0, x8]
+; CHECK-NEXT: and w10, w9, w10, lsl #2
+; CHECK-NEXT: str w10, [x0, x8]
; CHECK-NEXT: add x8, x8, #4
; CHECK-NEXT: cmp x8, #1024
; CHECK-NEXT: b.ne .LBB38_1
More information about the llvm-commits
mailing list