| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+experimental-v,+f \ |
| ; RUN: -riscv-v-vector-bits-min=128 | FileCheck %s |
| |
| define void @sink_splat_mul(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_mul: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB0_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vmul.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB0_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = mul <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_add(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_add: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB1_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vadd.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB1_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = add <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_sub(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_sub: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB2_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vadd.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB2_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = add <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_rsub(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_rsub: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB3_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vrsub.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB3_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = sub <4 x i32> %broadcast.splat, %wide.load |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_and(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_and: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB4_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vand.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB4_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = and <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_or(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_or: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB5_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vor.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB5_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = or <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_xor(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_xor: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB6_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vxor.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB6_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = xor <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_mul_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_mul_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB7_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB7_5 |
| ; CHECK-NEXT: .LBB7_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB7_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vmul.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB7_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB7_7 |
| ; CHECK-NEXT: .LBB7_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB7_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: mulw a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB7_6 |
| ; CHECK-NEXT: .LBB7_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = mul <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %mul = mul i32 %11, %x |
| store i32 %mul, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_add_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_add_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB8_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB8_5 |
| ; CHECK-NEXT: .LBB8_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB8_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vadd.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB8_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB8_7 |
| ; CHECK-NEXT: .LBB8_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB8_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: addw a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB8_6 |
| ; CHECK-NEXT: .LBB8_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = add <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %add = add i32 %11, %x |
| store i32 %add, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_sub_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_sub_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB9_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB9_5 |
| ; CHECK-NEXT: .LBB9_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB9_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vsub.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB9_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB9_7 |
| ; CHECK-NEXT: .LBB9_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB9_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: addw a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB9_6 |
| ; CHECK-NEXT: .LBB9_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = sub <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %add = add i32 %11, %x |
| store i32 %add, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_rsub_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_rsub_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB10_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB10_5 |
| ; CHECK-NEXT: .LBB10_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB10_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vrsub.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB10_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB10_7 |
| ; CHECK-NEXT: .LBB10_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB10_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: subw a2, a1, a3 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB10_6 |
| ; CHECK-NEXT: .LBB10_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = sub <vscale x 4 x i32> %broadcast.splat, %wide.load |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %add = sub i32 %x, %11 |
| store i32 %add, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_and_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_and_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB11_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB11_5 |
| ; CHECK-NEXT: .LBB11_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB11_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vand.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB11_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB11_7 |
| ; CHECK-NEXT: .LBB11_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB11_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: and a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB11_6 |
| ; CHECK-NEXT: .LBB11_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = and <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %and = and i32 %11, %x |
| store i32 %and, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_or_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_or_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB12_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB12_5 |
| ; CHECK-NEXT: .LBB12_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB12_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vor.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB12_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB12_7 |
| ; CHECK-NEXT: .LBB12_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB12_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: or a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB12_6 |
| ; CHECK-NEXT: .LBB12_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = or <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %or = or i32 %11, %x |
| store i32 %or, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_xor_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_xor_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB13_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB13_5 |
| ; CHECK-NEXT: .LBB13_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB13_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vxor.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB13_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB13_7 |
| ; CHECK-NEXT: .LBB13_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB13_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: xor a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB13_6 |
| ; CHECK-NEXT: .LBB13_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = xor <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %xor = xor i32 %11, %x |
| store i32 %xor, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_shl(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_shl: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB14_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vsll.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB14_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = shl <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_lshr(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_lshr: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB15_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vsrl.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB15_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = lshr <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_ashr(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_ashr: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB16_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vsra.vx v8, v8, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB16_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %a, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = ashr <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| store <4 x i32> %2, <4 x i32>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_shl_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_shl_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB17_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB17_5 |
| ; CHECK-NEXT: .LBB17_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB17_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vsll.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB17_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB17_7 |
| ; CHECK-NEXT: .LBB17_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB17_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: sllw a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB17_6 |
| ; CHECK-NEXT: .LBB17_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = shl <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %shl = shl i32 %11, %x |
| store i32 %shl, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_lshr_scalable(i32* nocapture %a, i32 signext %x) { |
| ; CHECK-LABEL: sink_splat_lshr_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a2, vlenb |
| ; CHECK-NEXT: srli a7, a2, 1 |
| ; CHECK-NEXT: li a3, 1024 |
| ; CHECK-NEXT: bgeu a3, a7, .LBB18_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB18_5 |
| ; CHECK-NEXT: .LBB18_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a3, a7 |
| ; CHECK-NEXT: sub t0, a3, a6 |
| ; CHECK-NEXT: slli a4, a2, 1 |
| ; CHECK-NEXT: mv a2, a0 |
| ; CHECK-NEXT: .LBB18_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a2) |
| ; CHECK-NEXT: vsetvli a3, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vsrl.vx v8, v8, a1 |
| ; CHECK-NEXT: vs2r.v v8, (a2) |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: add a2, a2, a4 |
| ; CHECK-NEXT: bne a5, t0, .LBB18_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB18_7 |
| ; CHECK-NEXT: .LBB18_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, t0, -1024 |
| ; CHECK-NEXT: slli a3, t0, 2 |
| ; CHECK-NEXT: add a0, a0, a3 |
| ; CHECK-NEXT: .LBB18_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a3, 0(a0) |
| ; CHECK-NEXT: mv a4, a2 |
| ; CHECK-NEXT: srlw a2, a3, a1 |
| ; CHECK-NEXT: sw a2, 0(a0) |
| ; CHECK-NEXT: addi a2, a4, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a4, .LBB18_6 |
| ; CHECK-NEXT: .LBB18_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = lshr <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %lshr = lshr i32 %11, %x |
| store i32 %lshr, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_ashr_scalable(i32* nocapture %a) { |
| ; CHECK-LABEL: sink_splat_ashr_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a3, vlenb |
| ; CHECK-NEXT: srli a7, a3, 1 |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: bgeu a2, a7, .LBB19_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a2, 0 |
| ; CHECK-NEXT: j .LBB19_5 |
| ; CHECK-NEXT: .LBB19_2: # %vector.ph |
| ; CHECK-NEXT: li a4, 0 |
| ; CHECK-NEXT: remu a6, a2, a7 |
| ; CHECK-NEXT: sub a2, a2, a6 |
| ; CHECK-NEXT: slli a5, a3, 1 |
| ; CHECK-NEXT: mv a3, a0 |
| ; CHECK-NEXT: .LBB19_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl2re32.v v8, (a3) |
| ; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu |
| ; CHECK-NEXT: vsra.vi v8, v8, 2 |
| ; CHECK-NEXT: vs2r.v v8, (a3) |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: add a3, a3, a5 |
| ; CHECK-NEXT: bne a4, a2, .LBB19_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB19_7 |
| ; CHECK-NEXT: .LBB19_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a1, a2, -1024 |
| ; CHECK-NEXT: slli a2, a2, 2 |
| ; CHECK-NEXT: add a0, a0, a2 |
| ; CHECK-NEXT: .LBB19_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: lw a2, 0(a0) |
| ; CHECK-NEXT: mv a3, a1 |
| ; CHECK-NEXT: srli a1, a2, 2 |
| ; CHECK-NEXT: sw a1, 0(a0) |
| ; CHECK-NEXT: addi a1, a3, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a1, a3, .LBB19_6 |
| ; CHECK-NEXT: .LBB19_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 2 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 2 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 4 x i32> poison, i32 2, i32 0 |
| %broadcast.splat = shufflevector <vscale x 4 x i32> %broadcast.splatinsert, <vscale x 4 x i32> poison, <vscale x 4 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 2 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds i32, i32* %a, i64 %index |
| %7 = bitcast i32* %6 to <vscale x 4 x i32>* |
| %wide.load = load <vscale x 4 x i32>, <vscale x 4 x i32>* %7, align 4 |
| %8 = ashr <vscale x 4 x i32> %wide.load, %broadcast.splat |
| %9 = bitcast i32* %6 to <vscale x 4 x i32>* |
| store <vscale x 4 x i32> %8, <vscale x 4 x i32>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds i32, i32* %a, i64 %indvars.iv |
| %11 = load i32, i32* %arrayidx, align 4 |
| %ashr = ashr i32 %11, 2 |
| store i32 %ashr, i32* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fmul(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fmul: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB20_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfmul.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB20_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fmul <4 x float> %wide.load, %broadcast.splat |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fdiv(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fdiv: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB21_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfdiv.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB21_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fdiv <4 x float> %wide.load, %broadcast.splat |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_frdiv(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_frdiv: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB22_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfrdiv.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB22_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fdiv <4 x float> %broadcast.splat, %wide.load |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fadd(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fadd: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB23_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfadd.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB23_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fadd <4 x float> %wide.load, %broadcast.splat |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fsub(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fsub: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB24_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfsub.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB24_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fsub <4 x float> %wide.load, %broadcast.splat |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_frsub(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_frsub: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: .LBB25_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vfrsub.vf v8, v8, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0) |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB25_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fsub <4 x float> %broadcast.splat, %wide.load |
| %3 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %2, <4 x float>* %3, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fmul_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fmul_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB26_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB26_5 |
| ; CHECK-NEXT: .LBB26_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB26_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfmul.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB26_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB26_7 |
| ; CHECK-NEXT: .LBB26_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB26_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fmul.s ft1, ft1, ft0 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB26_6 |
| ; CHECK-NEXT: .LBB26_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fmul <vscale x 2 x float> %wide.load, %broadcast.splat |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fmul float %11, %x |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fdiv_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fdiv_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB27_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB27_5 |
| ; CHECK-NEXT: .LBB27_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB27_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfdiv.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB27_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB27_7 |
| ; CHECK-NEXT: .LBB27_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB27_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fdiv.s ft1, ft1, ft0 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB27_6 |
| ; CHECK-NEXT: .LBB27_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fdiv <vscale x 2 x float> %wide.load, %broadcast.splat |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fdiv float %11, %x |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_frdiv_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_frdiv_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB28_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB28_5 |
| ; CHECK-NEXT: .LBB28_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB28_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfrdiv.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB28_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB28_7 |
| ; CHECK-NEXT: .LBB28_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB28_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fdiv.s ft1, ft0, ft1 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB28_6 |
| ; CHECK-NEXT: .LBB28_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fdiv <vscale x 2 x float> %broadcast.splat, %wide.load |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fdiv float %x, %11 |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fadd_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fadd_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB29_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB29_5 |
| ; CHECK-NEXT: .LBB29_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB29_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfadd.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB29_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB29_7 |
| ; CHECK-NEXT: .LBB29_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB29_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fadd.s ft1, ft1, ft0 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB29_6 |
| ; CHECK-NEXT: .LBB29_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fadd <vscale x 2 x float> %wide.load, %broadcast.splat |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fadd float %11, %x |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fsub_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_fsub_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB30_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB30_5 |
| ; CHECK-NEXT: .LBB30_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB30_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfsub.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB30_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB30_7 |
| ; CHECK-NEXT: .LBB30_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB30_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fsub.s ft1, ft1, ft0 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB30_6 |
| ; CHECK-NEXT: .LBB30_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fsub <vscale x 2 x float> %wide.load, %broadcast.splat |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fsub float %11, %x |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_frsub_scalable(float* nocapture %a, float %x) { |
| ; CHECK-LABEL: sink_splat_frsub_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli a3, a7, 2 |
| ; CHECK-NEXT: li a4, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: bgeu a4, a3, .LBB31_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: j .LBB31_5 |
| ; CHECK-NEXT: .LBB31_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: remu a6, a4, a3 |
| ; CHECK-NEXT: sub a1, a4, a6 |
| ; CHECK-NEXT: mv a4, a0 |
| ; CHECK-NEXT: .LBB31_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vl1re32.v v8, (a4) |
| ; CHECK-NEXT: vsetvli a2, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfrsub.vf v8, v8, ft0 |
| ; CHECK-NEXT: vs1r.v v8, (a4) |
| ; CHECK-NEXT: add a5, a5, a3 |
| ; CHECK-NEXT: add a4, a4, a7 |
| ; CHECK-NEXT: bne a5, a1, .LBB31_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB31_7 |
| ; CHECK-NEXT: .LBB31_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a2, a1, -1024 |
| ; CHECK-NEXT: slli a1, a1, 2 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: .LBB31_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: mv a1, a2 |
| ; CHECK-NEXT: fsub.s ft1, ft0, ft1 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a2, a2, 1 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a2, a1, .LBB31_6 |
| ; CHECK-NEXT: .LBB31_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = fsub <vscale x 2 x float> %broadcast.splat, %wide.load |
| %9 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %8, <vscale x 2 x float>* %9, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %10 = icmp eq i64 %index.next, %n.vec |
| br i1 %10, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %11 = load float, float* %arrayidx, align 4 |
| %mul = fsub float %x, %11 |
| store float %mul, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fma(float* noalias nocapture %a, float* nocapture readonly %b, float %x) { |
| ; CHECK-LABEL: sink_splat_fma: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a2 |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB32_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vle32.v v9, (a1) |
| ; CHECK-NEXT: vfmacc.vf v9, ft0, v8 |
| ; CHECK-NEXT: vse32.v v9, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a1, a1, 16 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB32_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = getelementptr inbounds float, float* %b, i64 %index |
| %3 = bitcast float* %2 to <4 x float>* |
| %wide.load12 = load <4 x float>, <4 x float>* %3, align 4 |
| %4 = call <4 x float> @llvm.fma.v4f32(<4 x float> %wide.load, <4 x float> %broadcast.splat, <4 x float> %wide.load12) |
| %5 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %4, <4 x float>* %5, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %6 = icmp eq i64 %index.next, 1024 |
| br i1 %6, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fma_commute(float* noalias nocapture %a, float* nocapture readonly %b, float %x) { |
| ; CHECK-LABEL: sink_splat_fma_commute: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a2 |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: .LBB33_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vle32.v v8, (a0) |
| ; CHECK-NEXT: vle32.v v9, (a1) |
| ; CHECK-NEXT: vfmacc.vf v9, ft0, v8 |
| ; CHECK-NEXT: vse32.v v9, (a0) |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a1, a1, 16 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB33_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %a, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = getelementptr inbounds float, float* %b, i64 %index |
| %3 = bitcast float* %2 to <4 x float>* |
| %wide.load12 = load <4 x float>, <4 x float>* %3, align 4 |
| %4 = call <4 x float> @llvm.fma.v4f32(<4 x float> %broadcast.splat, <4 x float> %wide.load, <4 x float> %wide.load12) |
| %5 = bitcast float* %0 to <4 x float>* |
| store <4 x float> %4, <4 x float>* %5, align 4 |
| %index.next = add nuw i64 %index, 4 |
| %6 = icmp eq i64 %index.next, 1024 |
| br i1 %6, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| |
| define void @sink_splat_fma_scalable(float* noalias nocapture %a, float* noalias nocapture readonly %b, float %x) { |
| ; CHECK-LABEL: sink_splat_fma_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli t1, a7, 2 |
| ; CHECK-NEXT: li t0, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a2 |
| ; CHECK-NEXT: bgeu t0, t1, .LBB34_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB34_5 |
| ; CHECK-NEXT: .LBB34_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: li a3, 0 |
| ; CHECK-NEXT: remu a6, t0, t1 |
| ; CHECK-NEXT: sub t0, t0, a6 |
| ; CHECK-NEXT: .LBB34_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: add a2, a0, a5 |
| ; CHECK-NEXT: vl1re32.v v8, (a2) |
| ; CHECK-NEXT: add a4, a1, a5 |
| ; CHECK-NEXT: vl1re32.v v9, (a4) |
| ; CHECK-NEXT: vsetvli a4, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfmacc.vf v9, ft0, v8 |
| ; CHECK-NEXT: vs1r.v v9, (a2) |
| ; CHECK-NEXT: add a3, a3, t1 |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: bne a3, t0, .LBB34_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB34_7 |
| ; CHECK-NEXT: .LBB34_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a3, t0, -1024 |
| ; CHECK-NEXT: slli a2, t0, 2 |
| ; CHECK-NEXT: add a1, a1, a2 |
| ; CHECK-NEXT: add a0, a0, a2 |
| ; CHECK-NEXT: .LBB34_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: flw ft2, 0(a1) |
| ; CHECK-NEXT: mv a2, a3 |
| ; CHECK-NEXT: fmadd.s ft1, ft1, ft0, ft2 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a3, a3, 1 |
| ; CHECK-NEXT: addi a1, a1, 4 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a3, a2, .LBB34_6 |
| ; CHECK-NEXT: .LBB34_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = getelementptr inbounds float, float* %b, i64 %index |
| %9 = bitcast float* %8 to <vscale x 2 x float>* |
| %wide.load12 = load <vscale x 2 x float>, <vscale x 2 x float>* %9, align 4 |
| %10 = call <vscale x 2 x float> @llvm.fma.nxv2f32(<vscale x 2 x float> %wide.load, <vscale x 2 x float> %broadcast.splat, <vscale x 2 x float> %wide.load12) |
| %11 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %10, <vscale x 2 x float>* %11, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %12 = icmp eq i64 %index.next, %n.vec |
| br i1 %12, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %13 = load float, float* %arrayidx, align 4 |
| %arrayidx2 = getelementptr inbounds float, float* %b, i64 %indvars.iv |
| %14 = load float, float* %arrayidx2, align 4 |
| %15 = tail call float @llvm.fma.f32(float %13, float %x, float %14) |
| store float %15, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| define void @sink_splat_fma_commute_scalable(float* noalias nocapture %a, float* noalias nocapture readonly %b, float %x) { |
| ; CHECK-LABEL: sink_splat_fma_commute_scalable: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: csrr a7, vlenb |
| ; CHECK-NEXT: srli t1, a7, 2 |
| ; CHECK-NEXT: li t0, 1024 |
| ; CHECK-NEXT: fmv.w.x ft0, a2 |
| ; CHECK-NEXT: bgeu t0, t1, .LBB35_2 |
| ; CHECK-NEXT: # %bb.1: |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: j .LBB35_5 |
| ; CHECK-NEXT: .LBB35_2: # %vector.ph |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: li a3, 0 |
| ; CHECK-NEXT: remu a6, t0, t1 |
| ; CHECK-NEXT: sub t0, t0, a6 |
| ; CHECK-NEXT: .LBB35_3: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: add a2, a0, a5 |
| ; CHECK-NEXT: vl1re32.v v8, (a2) |
| ; CHECK-NEXT: add a4, a1, a5 |
| ; CHECK-NEXT: vl1re32.v v9, (a4) |
| ; CHECK-NEXT: vsetvli a4, zero, e32, m1, ta, mu |
| ; CHECK-NEXT: vfmacc.vf v9, ft0, v8 |
| ; CHECK-NEXT: vs1r.v v9, (a2) |
| ; CHECK-NEXT: add a3, a3, t1 |
| ; CHECK-NEXT: add a5, a5, a7 |
| ; CHECK-NEXT: bne a3, t0, .LBB35_3 |
| ; CHECK-NEXT: # %bb.4: # %middle.block |
| ; CHECK-NEXT: beqz a6, .LBB35_7 |
| ; CHECK-NEXT: .LBB35_5: # %for.body.preheader |
| ; CHECK-NEXT: addi a3, t0, -1024 |
| ; CHECK-NEXT: slli a2, t0, 2 |
| ; CHECK-NEXT: add a1, a1, a2 |
| ; CHECK-NEXT: add a0, a0, a2 |
| ; CHECK-NEXT: .LBB35_6: # %for.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: flw ft1, 0(a0) |
| ; CHECK-NEXT: flw ft2, 0(a1) |
| ; CHECK-NEXT: mv a2, a3 |
| ; CHECK-NEXT: fmadd.s ft1, ft0, ft1, ft2 |
| ; CHECK-NEXT: fsw ft1, 0(a0) |
| ; CHECK-NEXT: addi a3, a3, 1 |
| ; CHECK-NEXT: addi a1, a1, 4 |
| ; CHECK-NEXT: addi a0, a0, 4 |
| ; CHECK-NEXT: bgeu a3, a2, .LBB35_6 |
| ; CHECK-NEXT: .LBB35_7: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %0 = call i64 @llvm.vscale.i64() |
| %1 = shl i64 %0, 1 |
| %min.iters.check = icmp ugt i64 %1, 1024 |
| br i1 %min.iters.check, label %for.body.preheader, label %vector.ph |
| |
| vector.ph: ; preds = %entry |
| %2 = call i64 @llvm.vscale.i64() |
| %3 = shl i64 %2, 1 |
| %n.mod.vf = urem i64 1024, %3 |
| %n.vec = sub nsw i64 1024, %n.mod.vf |
| %broadcast.splatinsert = insertelement <vscale x 2 x float> poison, float %x, i32 0 |
| %broadcast.splat = shufflevector <vscale x 2 x float> %broadcast.splatinsert, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer |
| %4 = call i64 @llvm.vscale.i64() |
| %5 = shl i64 %4, 1 |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %vector.ph |
| %index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ] |
| %6 = getelementptr inbounds float, float* %a, i64 %index |
| %7 = bitcast float* %6 to <vscale x 2 x float>* |
| %wide.load = load <vscale x 2 x float>, <vscale x 2 x float>* %7, align 4 |
| %8 = getelementptr inbounds float, float* %b, i64 %index |
| %9 = bitcast float* %8 to <vscale x 2 x float>* |
| %wide.load12 = load <vscale x 2 x float>, <vscale x 2 x float>* %9, align 4 |
| %10 = call <vscale x 2 x float> @llvm.fma.nxv2f32(<vscale x 2 x float> %broadcast.splat, <vscale x 2 x float> %wide.load, <vscale x 2 x float> %wide.load12) |
| %11 = bitcast float* %6 to <vscale x 2 x float>* |
| store <vscale x 2 x float> %10, <vscale x 2 x float>* %11, align 4 |
| %index.next = add nuw i64 %index, %5 |
| %12 = icmp eq i64 %index.next, %n.vec |
| br i1 %12, label %middle.block, label %vector.body |
| |
| middle.block: ; preds = %vector.body |
| %cmp.n = icmp eq i64 %n.mod.vf, 0 |
| br i1 %cmp.n, label %for.cond.cleanup, label %for.body.preheader |
| |
| for.body.preheader: ; preds = %entry, %middle.block |
| %indvars.iv.ph = phi i64 [ 0, %entry ], [ %n.vec, %middle.block ] |
| br label %for.body |
| |
| for.cond.cleanup: ; preds = %for.body, %middle.block |
| ret void |
| |
| for.body: ; preds = %for.body.preheader, %for.body |
| %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ %indvars.iv.ph, %for.body.preheader ] |
| %arrayidx = getelementptr inbounds float, float* %a, i64 %indvars.iv |
| %13 = load float, float* %arrayidx, align 4 |
| %arrayidx2 = getelementptr inbounds float, float* %b, i64 %indvars.iv |
| %14 = load float, float* %arrayidx2, align 4 |
| %15 = tail call float @llvm.fma.f32(float %x, float %13, float %14) |
| store float %15, float* %arrayidx, align 4 |
| %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 |
| %cmp.not = icmp eq i64 %indvars.iv.next, 1024 |
| br i1 %cmp.not, label %for.cond.cleanup, label %for.body |
| } |
| |
| declare i64 @llvm.vscale.i64() |
| declare <4 x float> @llvm.fma.v4f32(<4 x float>, <4 x float>, <4 x float>) |
| declare <vscale x 2 x float> @llvm.fma.nxv2f32(<vscale x 2 x float>, <vscale x 2 x float>, <vscale x 2 x float>) |
| declare float @llvm.fma.f32(float, float, float) |
| |
| define void @sink_splat_icmp(i32* nocapture %x, i32 signext %y) { |
| ; CHECK-LABEL: sink_splat_icmp: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: li a2, 1024 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vmv.v.i v8, 0 |
| ; CHECK-NEXT: .LBB36_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vle32.v v9, (a0) |
| ; CHECK-NEXT: vmseq.vx v0, v9, a1 |
| ; CHECK-NEXT: vse32.v v8, (a0), v0.t |
| ; CHECK-NEXT: addi a2, a2, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a2, .LBB36_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x i32> poison, i32 %y, i32 0 |
| %broadcast.splat = shufflevector <4 x i32> %broadcast.splatinsert, <4 x i32> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds i32, i32* %x, i64 %index |
| %1 = bitcast i32* %0 to <4 x i32>* |
| %wide.load = load <4 x i32>, <4 x i32>* %1, align 4 |
| %2 = icmp eq <4 x i32> %wide.load, %broadcast.splat |
| %3 = bitcast i32* %0 to <4 x i32>* |
| call void @llvm.masked.store.v4i32.p0v4i32(<4 x i32> zeroinitializer, <4 x i32>* %3, i32 4, <4 x i1> %2) |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| declare void @llvm.masked.store.v4i32.p0v4i32(<4 x i32>, <4 x i32>*, i32, <4 x i1>) |
| |
| define void @sink_splat_fcmp(float* nocapture %x, float %y) { |
| ; CHECK-LABEL: sink_splat_fcmp: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fmv.w.x ft0, a1 |
| ; CHECK-NEXT: li a1, 1024 |
| ; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, mu |
| ; CHECK-NEXT: vmv.v.i v8, 0 |
| ; CHECK-NEXT: .LBB37_1: # %vector.body |
| ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 |
| ; CHECK-NEXT: vle32.v v9, (a0) |
| ; CHECK-NEXT: vmfeq.vf v0, v9, ft0 |
| ; CHECK-NEXT: vse32.v v8, (a0), v0.t |
| ; CHECK-NEXT: addi a1, a1, -4 |
| ; CHECK-NEXT: addi a0, a0, 16 |
| ; CHECK-NEXT: bnez a1, .LBB37_1 |
| ; CHECK-NEXT: # %bb.2: # %for.cond.cleanup |
| ; CHECK-NEXT: ret |
| entry: |
| %broadcast.splatinsert = insertelement <4 x float> poison, float %y, i32 0 |
| %broadcast.splat = shufflevector <4 x float> %broadcast.splatinsert, <4 x float> poison, <4 x i32> zeroinitializer |
| br label %vector.body |
| |
| vector.body: ; preds = %vector.body, %entry |
| %index = phi i64 [ 0, %entry ], [ %index.next, %vector.body ] |
| %0 = getelementptr inbounds float, float* %x, i64 %index |
| %1 = bitcast float* %0 to <4 x float>* |
| %wide.load = load <4 x float>, <4 x float>* %1, align 4 |
| %2 = fcmp fast oeq <4 x float> %wide.load, %broadcast.splat |
| %3 = bitcast float* %0 to <4 x float>* |
| call void @llvm.masked.store.v4f32.p0v4f32(<4 x float> zeroinitializer, <4 x float>* %3, i32 4, <4 x i1> %2) |
| %index.next = add nuw i64 %index, 4 |
| %4 = icmp eq i64 %index.next, 1024 |
| br i1 %4, label %for.cond.cleanup, label %vector.body |
| |
| for.cond.cleanup: ; preds = %vector.body |
| ret void |
| } |
| declare void @llvm.masked.store.v4f32.p0v4f32(<4 x float>, <4 x float>*, i32, <4 x i1>) |