blob: 35ce7fad0ea677e99e37eda3fa858655dce31b0b [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc < %s -mtriple=riscv32 -mattr=+m \
; RUN: | FileCheck %s --check-prefixes=RV32-BOTH,RV32
; RUN: llc < %s -mtriple=riscv64 -mattr=+m \
; RUN: | FileCheck %s --check-prefixes=RV64-BOTH,RV64
; RUN: llc < %s -mtriple=riscv32 -mattr=+m,+unaligned-scalar-mem \
; RUN: | FileCheck %s --check-prefixes=RV32-BOTH,RV32-FAST
; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+unaligned-scalar-mem \
; RUN: | FileCheck %s --check-prefixes=RV64-BOTH,RV64-FAST
; TODO: Due to the initial naive lowering implementation of memset.pattern in
; PreISelIntrinsicLowering, the generated code is not good.
define void @memset_1(ptr %a, i128 %value) nounwind {
; RV32-BOTH-LABEL: memset_1:
; RV32-BOTH: # %bb.0: # %loadstoreloop.preheader
; RV32-BOTH-NEXT: li a2, 0
; RV32-BOTH-NEXT: lw a3, 0(a1)
; RV32-BOTH-NEXT: lw a4, 4(a1)
; RV32-BOTH-NEXT: lw a5, 8(a1)
; RV32-BOTH-NEXT: lw a1, 12(a1)
; RV32-BOTH-NEXT: li a6, 0
; RV32-BOTH-NEXT: .LBB0_1: # %loadstoreloop
; RV32-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-BOTH-NEXT: slli a7, a2, 4
; RV32-BOTH-NEXT: addi a2, a2, 1
; RV32-BOTH-NEXT: add a7, a0, a7
; RV32-BOTH-NEXT: seqz t0, a2
; RV32-BOTH-NEXT: add a6, a6, t0
; RV32-BOTH-NEXT: or t0, a2, a6
; RV32-BOTH-NEXT: sw a3, 0(a7)
; RV32-BOTH-NEXT: sw a4, 4(a7)
; RV32-BOTH-NEXT: sw a5, 8(a7)
; RV32-BOTH-NEXT: sw a1, 12(a7)
; RV32-BOTH-NEXT: beqz t0, .LBB0_1
; RV32-BOTH-NEXT: # %bb.2: # %split
; RV32-BOTH-NEXT: ret
;
; RV64-BOTH-LABEL: memset_1:
; RV64-BOTH: # %bb.0: # %loadstoreloop.preheader
; RV64-BOTH-NEXT: addi a3, a0, 16
; RV64-BOTH-NEXT: .LBB0_1: # %loadstoreloop
; RV64-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-BOTH-NEXT: sd a1, 0(a0)
; RV64-BOTH-NEXT: sd a2, 8(a0)
; RV64-BOTH-NEXT: addi a0, a0, 16
; RV64-BOTH-NEXT: bne a0, a3, .LBB0_1
; RV64-BOTH-NEXT: # %bb.2: # %split
; RV64-BOTH-NEXT: ret
tail call void @llvm.experimental.memset.pattern(ptr align 8 %a, i128 %value, i64 1, i1 0)
ret void
}
define void @memset_1_noalign(ptr %a, i128 %value) nounwind {
; RV32-LABEL: memset_1_noalign:
; RV32: # %bb.0: # %loadstoreloop.preheader
; RV32-NEXT: addi sp, sp, -32
; RV32-NEXT: sw s0, 28(sp) # 4-byte Folded Spill
; RV32-NEXT: sw s1, 24(sp) # 4-byte Folded Spill
; RV32-NEXT: sw s2, 20(sp) # 4-byte Folded Spill
; RV32-NEXT: sw s3, 16(sp) # 4-byte Folded Spill
; RV32-NEXT: sw s4, 12(sp) # 4-byte Folded Spill
; RV32-NEXT: sw s5, 8(sp) # 4-byte Folded Spill
; RV32-NEXT: li a2, 0
; RV32-NEXT: li a3, 0
; RV32-NEXT: lw a4, 4(a1)
; RV32-NEXT: lw a5, 0(a1)
; RV32-NEXT: lw a6, 8(a1)
; RV32-NEXT: lw a1, 12(a1)
; RV32-NEXT: srli a7, a4, 24
; RV32-NEXT: srli t0, a4, 16
; RV32-NEXT: srli t1, a4, 8
; RV32-NEXT: srli t2, a5, 24
; RV32-NEXT: srli t3, a5, 16
; RV32-NEXT: srli t4, a5, 8
; RV32-NEXT: srli t5, a6, 24
; RV32-NEXT: srli t6, a6, 16
; RV32-NEXT: srli s0, a6, 8
; RV32-NEXT: srli s1, a1, 24
; RV32-NEXT: srli s2, a1, 16
; RV32-NEXT: srli s3, a1, 8
; RV32-NEXT: .LBB1_1: # %loadstoreloop
; RV32-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-NEXT: slli s4, a2, 4
; RV32-NEXT: addi a2, a2, 1
; RV32-NEXT: add s4, a0, s4
; RV32-NEXT: seqz s5, a2
; RV32-NEXT: sb a4, 4(s4)
; RV32-NEXT: sb t1, 5(s4)
; RV32-NEXT: sb t0, 6(s4)
; RV32-NEXT: sb a7, 7(s4)
; RV32-NEXT: sb a5, 0(s4)
; RV32-NEXT: sb t4, 1(s4)
; RV32-NEXT: sb t3, 2(s4)
; RV32-NEXT: sb t2, 3(s4)
; RV32-NEXT: sb a6, 8(s4)
; RV32-NEXT: sb s0, 9(s4)
; RV32-NEXT: sb t6, 10(s4)
; RV32-NEXT: sb t5, 11(s4)
; RV32-NEXT: add a3, a3, s5
; RV32-NEXT: or s5, a2, a3
; RV32-NEXT: sb a1, 12(s4)
; RV32-NEXT: sb s3, 13(s4)
; RV32-NEXT: sb s2, 14(s4)
; RV32-NEXT: sb s1, 15(s4)
; RV32-NEXT: beqz s5, .LBB1_1
; RV32-NEXT: # %bb.2: # %split
; RV32-NEXT: lw s0, 28(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s1, 24(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s2, 20(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s3, 16(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s4, 12(sp) # 4-byte Folded Reload
; RV32-NEXT: lw s5, 8(sp) # 4-byte Folded Reload
; RV32-NEXT: addi sp, sp, 32
; RV32-NEXT: ret
;
; RV64-LABEL: memset_1_noalign:
; RV64: # %bb.0: # %loadstoreloop.preheader
; RV64-NEXT: addi sp, sp, -32
; RV64-NEXT: sd s0, 24(sp) # 8-byte Folded Spill
; RV64-NEXT: sd s1, 16(sp) # 8-byte Folded Spill
; RV64-NEXT: sd s2, 8(sp) # 8-byte Folded Spill
; RV64-NEXT: addi a3, a0, 16
; RV64-NEXT: srli a4, a1, 56
; RV64-NEXT: srli a5, a1, 48
; RV64-NEXT: srli a6, a1, 40
; RV64-NEXT: srli a7, a1, 32
; RV64-NEXT: srli t0, a1, 24
; RV64-NEXT: srli t1, a1, 16
; RV64-NEXT: srli t2, a1, 8
; RV64-NEXT: srli t3, a2, 56
; RV64-NEXT: srli t4, a2, 48
; RV64-NEXT: srli t5, a2, 40
; RV64-NEXT: srli t6, a2, 32
; RV64-NEXT: srli s0, a2, 24
; RV64-NEXT: srli s1, a2, 16
; RV64-NEXT: srli s2, a2, 8
; RV64-NEXT: .LBB1_1: # %loadstoreloop
; RV64-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-NEXT: sb a7, 4(a0)
; RV64-NEXT: sb a6, 5(a0)
; RV64-NEXT: sb a5, 6(a0)
; RV64-NEXT: sb a4, 7(a0)
; RV64-NEXT: sb a1, 0(a0)
; RV64-NEXT: sb t2, 1(a0)
; RV64-NEXT: sb t1, 2(a0)
; RV64-NEXT: sb t0, 3(a0)
; RV64-NEXT: sb t6, 12(a0)
; RV64-NEXT: sb t5, 13(a0)
; RV64-NEXT: sb t4, 14(a0)
; RV64-NEXT: sb t3, 15(a0)
; RV64-NEXT: sb a2, 8(a0)
; RV64-NEXT: sb s2, 9(a0)
; RV64-NEXT: sb s1, 10(a0)
; RV64-NEXT: sb s0, 11(a0)
; RV64-NEXT: addi a0, a0, 16
; RV64-NEXT: bne a0, a3, .LBB1_1
; RV64-NEXT: # %bb.2: # %split
; RV64-NEXT: ld s0, 24(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s1, 16(sp) # 8-byte Folded Reload
; RV64-NEXT: ld s2, 8(sp) # 8-byte Folded Reload
; RV64-NEXT: addi sp, sp, 32
; RV64-NEXT: ret
;
; RV32-FAST-LABEL: memset_1_noalign:
; RV32-FAST: # %bb.0: # %loadstoreloop.preheader
; RV32-FAST-NEXT: li a2, 0
; RV32-FAST-NEXT: lw a3, 0(a1)
; RV32-FAST-NEXT: lw a4, 4(a1)
; RV32-FAST-NEXT: lw a5, 8(a1)
; RV32-FAST-NEXT: lw a1, 12(a1)
; RV32-FAST-NEXT: li a6, 0
; RV32-FAST-NEXT: .LBB1_1: # %loadstoreloop
; RV32-FAST-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-FAST-NEXT: slli a7, a2, 4
; RV32-FAST-NEXT: addi a2, a2, 1
; RV32-FAST-NEXT: add a7, a0, a7
; RV32-FAST-NEXT: seqz t0, a2
; RV32-FAST-NEXT: add a6, a6, t0
; RV32-FAST-NEXT: or t0, a2, a6
; RV32-FAST-NEXT: sw a3, 0(a7)
; RV32-FAST-NEXT: sw a4, 4(a7)
; RV32-FAST-NEXT: sw a5, 8(a7)
; RV32-FAST-NEXT: sw a1, 12(a7)
; RV32-FAST-NEXT: beqz t0, .LBB1_1
; RV32-FAST-NEXT: # %bb.2: # %split
; RV32-FAST-NEXT: ret
;
; RV64-FAST-LABEL: memset_1_noalign:
; RV64-FAST: # %bb.0: # %loadstoreloop.preheader
; RV64-FAST-NEXT: addi a3, a0, 16
; RV64-FAST-NEXT: .LBB1_1: # %loadstoreloop
; RV64-FAST-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-FAST-NEXT: sd a1, 0(a0)
; RV64-FAST-NEXT: sd a2, 8(a0)
; RV64-FAST-NEXT: addi a0, a0, 16
; RV64-FAST-NEXT: bne a0, a3, .LBB1_1
; RV64-FAST-NEXT: # %bb.2: # %split
; RV64-FAST-NEXT: ret
tail call void @llvm.experimental.memset.pattern(ptr %a, i128 %value, i64 1, i1 0)
ret void
}
define void @memset_4(ptr %a, i128 %value) nounwind {
; RV32-BOTH-LABEL: memset_4:
; RV32-BOTH: # %bb.0: # %loadstoreloop.preheader
; RV32-BOTH-NEXT: li a2, 0
; RV32-BOTH-NEXT: lw a3, 0(a1)
; RV32-BOTH-NEXT: lw a4, 4(a1)
; RV32-BOTH-NEXT: lw a5, 8(a1)
; RV32-BOTH-NEXT: lw a1, 12(a1)
; RV32-BOTH-NEXT: li a6, 0
; RV32-BOTH-NEXT: .LBB2_1: # %loadstoreloop
; RV32-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-BOTH-NEXT: slli a7, a2, 4
; RV32-BOTH-NEXT: addi a2, a2, 1
; RV32-BOTH-NEXT: seqz t0, a2
; RV32-BOTH-NEXT: sltiu t1, a2, 4
; RV32-BOTH-NEXT: add a6, a6, t0
; RV32-BOTH-NEXT: seqz t0, a6
; RV32-BOTH-NEXT: and t0, t0, t1
; RV32-BOTH-NEXT: add a7, a0, a7
; RV32-BOTH-NEXT: sw a3, 0(a7)
; RV32-BOTH-NEXT: sw a4, 4(a7)
; RV32-BOTH-NEXT: sw a5, 8(a7)
; RV32-BOTH-NEXT: sw a1, 12(a7)
; RV32-BOTH-NEXT: bnez t0, .LBB2_1
; RV32-BOTH-NEXT: # %bb.2: # %split
; RV32-BOTH-NEXT: ret
;
; RV64-BOTH-LABEL: memset_4:
; RV64-BOTH: # %bb.0: # %loadstoreloop.preheader
; RV64-BOTH-NEXT: addi a3, a0, 64
; RV64-BOTH-NEXT: .LBB2_1: # %loadstoreloop
; RV64-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-BOTH-NEXT: sd a1, 0(a0)
; RV64-BOTH-NEXT: sd a2, 8(a0)
; RV64-BOTH-NEXT: addi a0, a0, 16
; RV64-BOTH-NEXT: bne a0, a3, .LBB2_1
; RV64-BOTH-NEXT: # %bb.2: # %split
; RV64-BOTH-NEXT: ret
tail call void @llvm.experimental.memset.pattern(ptr align 8 %a, i128 %value, i64 4, i1 0)
ret void
}
define void @memset_x(ptr %a, i128 %value, i64 %x) nounwind {
; RV32-BOTH-LABEL: memset_x:
; RV32-BOTH: # %bb.0:
; RV32-BOTH-NEXT: or a4, a2, a3
; RV32-BOTH-NEXT: beqz a4, .LBB3_5
; RV32-BOTH-NEXT: # %bb.1: # %loadstoreloop.preheader
; RV32-BOTH-NEXT: li a4, 0
; RV32-BOTH-NEXT: lw a5, 0(a1)
; RV32-BOTH-NEXT: lw a6, 4(a1)
; RV32-BOTH-NEXT: lw a7, 8(a1)
; RV32-BOTH-NEXT: lw a1, 12(a1)
; RV32-BOTH-NEXT: li t0, 0
; RV32-BOTH-NEXT: j .LBB3_3
; RV32-BOTH-NEXT: .LBB3_2: # %loadstoreloop
; RV32-BOTH-NEXT: # in Loop: Header=BB3_3 Depth=1
; RV32-BOTH-NEXT: sltu t1, t0, a3
; RV32-BOTH-NEXT: beqz t1, .LBB3_5
; RV32-BOTH-NEXT: .LBB3_3: # %loadstoreloop
; RV32-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-BOTH-NEXT: slli t1, a4, 4
; RV32-BOTH-NEXT: addi a4, a4, 1
; RV32-BOTH-NEXT: seqz t2, a4
; RV32-BOTH-NEXT: add t0, t0, t2
; RV32-BOTH-NEXT: add t1, a0, t1
; RV32-BOTH-NEXT: sw a5, 0(t1)
; RV32-BOTH-NEXT: sw a6, 4(t1)
; RV32-BOTH-NEXT: sw a7, 8(t1)
; RV32-BOTH-NEXT: sw a1, 12(t1)
; RV32-BOTH-NEXT: bne t0, a3, .LBB3_2
; RV32-BOTH-NEXT: # %bb.4: # in Loop: Header=BB3_3 Depth=1
; RV32-BOTH-NEXT: sltu t1, a4, a2
; RV32-BOTH-NEXT: bnez t1, .LBB3_3
; RV32-BOTH-NEXT: .LBB3_5: # %split
; RV32-BOTH-NEXT: ret
;
; RV64-BOTH-LABEL: memset_x:
; RV64-BOTH: # %bb.0:
; RV64-BOTH-NEXT: beqz a3, .LBB3_3
; RV64-BOTH-NEXT: # %bb.1: # %loadstoreloop.preheader
; RV64-BOTH-NEXT: li a4, 0
; RV64-BOTH-NEXT: .LBB3_2: # %loadstoreloop
; RV64-BOTH-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-BOTH-NEXT: sd a1, 0(a0)
; RV64-BOTH-NEXT: sd a2, 8(a0)
; RV64-BOTH-NEXT: addi a4, a4, 1
; RV64-BOTH-NEXT: addi a0, a0, 16
; RV64-BOTH-NEXT: bltu a4, a3, .LBB3_2
; RV64-BOTH-NEXT: .LBB3_3: # %split
; RV64-BOTH-NEXT: ret
tail call void @llvm.experimental.memset.pattern(ptr align 8 %a, i128 %value, i64 %x, i1 0)
ret void
}