| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc -mtriple=riscv64 -mattr=+c,+m -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck -check-prefixes=CHECK,NOSFB %s |
| ; RUN: llc -mtriple=riscv64 -mcpu=sifive-u74 -verify-machineinstrs < %s \ |
| ; RUN: | FileCheck -check-prefixes=CHECK,SFB %s |
| |
| define signext i32 @sdiv2_32(i32 signext %0) { |
| ; NOSFB-LABEL: sdiv2_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srliw a1, a0, 31 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: sraiw a0, a0, 1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdiv2_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB0_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 1 |
| ; SFB-NEXT: .LBB0_2: |
| ; SFB-NEXT: sraiw a0, a0, 1 |
| ; SFB-NEXT: ret |
| %res = sdiv i32 %0, 2 |
| ret i32 %res |
| } |
| |
| define signext i32 @sdivneg2_32(i32 signext %0) { |
| ; NOSFB-LABEL: sdivneg2_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srliw a1, a0, 31 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: sraiw a0, a0, 1 |
| ; NOSFB-NEXT: neg a0, a0 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdivneg2_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB1_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 1 |
| ; SFB-NEXT: .LBB1_2: |
| ; SFB-NEXT: sraiw a0, a0, 1 |
| ; SFB-NEXT: neg a0, a0 |
| ; SFB-NEXT: ret |
| %res = sdiv i32 %0, -2 |
| ret i32 %res |
| } |
| |
| define i64 @sdiv2_64(i64 %0) { |
| ; NOSFB-LABEL: sdiv2_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srli a1, a0, 63 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: srai a0, a0, 1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdiv2_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB2_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 1 |
| ; SFB-NEXT: .LBB2_2: |
| ; SFB-NEXT: srai a0, a0, 1 |
| ; SFB-NEXT: ret |
| %res = sdiv i64 %0, 2 |
| ret i64 %res |
| } |
| |
| define i64 @sdivneg2_64(i64 %0) { |
| ; NOSFB-LABEL: sdivneg2_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srli a1, a0, 63 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: srai a0, a0, 1 |
| ; NOSFB-NEXT: neg a0, a0 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdivneg2_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB3_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 1 |
| ; SFB-NEXT: .LBB3_2: |
| ; SFB-NEXT: srai a0, a0, 1 |
| ; SFB-NEXT: neg a0, a0 |
| ; SFB-NEXT: ret |
| %res = sdiv i64 %0, -2 |
| ret i64 %res |
| } |
| |
| define signext i32 @srem2_32(i32 signext %0) { |
| ; NOSFB-LABEL: srem2_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srliw a1, a0, 31 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -2 |
| ; NOSFB-NEXT: subw a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: srem2_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB4_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 1 |
| ; SFB-NEXT: .LBB4_2: |
| ; SFB-NEXT: andi a1, a1, -2 |
| ; SFB-NEXT: subw a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i32 %0, 2 |
| ret i32 %res |
| } |
| |
| define signext i32 @sremneg2_32(i32 signext %0) { |
| ; NOSFB-LABEL: sremneg2_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srliw a1, a0, 31 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -2 |
| ; NOSFB-NEXT: subw a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sremneg2_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB5_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 1 |
| ; SFB-NEXT: .LBB5_2: |
| ; SFB-NEXT: andi a1, a1, -2 |
| ; SFB-NEXT: subw a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i32 %0, -2 |
| ret i32 %res |
| } |
| |
| define i64 @srem2_64(i64 %0) { |
| ; NOSFB-LABEL: srem2_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srli a1, a0, 63 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -2 |
| ; NOSFB-NEXT: sub a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: srem2_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB6_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 1 |
| ; SFB-NEXT: .LBB6_2: |
| ; SFB-NEXT: andi a1, a1, -2 |
| ; SFB-NEXT: sub a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i64 %0, 2 |
| ret i64 %res |
| } |
| |
| define i64 @sremneg2_64(i64 %0) { |
| ; NOSFB-LABEL: sremneg2_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srli a1, a0, 63 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -2 |
| ; NOSFB-NEXT: sub a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sremneg2_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB7_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 1 |
| ; SFB-NEXT: .LBB7_2: |
| ; SFB-NEXT: andi a1, a1, -2 |
| ; SFB-NEXT: sub a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i64 %0, -2 |
| ret i64 %res |
| } |
| |
| define signext i32 @sdiv8_32(i32 signext %0) { |
| ; NOSFB-LABEL: sdiv8_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: slli a1, a0, 1 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: sraiw a0, a0, 3 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdiv8_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB8_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 7 |
| ; SFB-NEXT: .LBB8_2: |
| ; SFB-NEXT: sraiw a0, a0, 3 |
| ; SFB-NEXT: ret |
| %res = sdiv i32 %0, 8 |
| ret i32 %res |
| } |
| |
| define signext i32 @sdivneg8_32(i32 signext %0) { |
| ; NOSFB-LABEL: sdivneg8_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: slli a1, a0, 1 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: sraiw a0, a0, 3 |
| ; NOSFB-NEXT: neg a0, a0 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdivneg8_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB9_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 7 |
| ; SFB-NEXT: .LBB9_2: |
| ; SFB-NEXT: sraiw a0, a0, 3 |
| ; SFB-NEXT: neg a0, a0 |
| ; SFB-NEXT: ret |
| %res = sdiv i32 %0, -8 |
| ret i32 %res |
| } |
| |
| define i64 @sdiv8_64(i64 %0) { |
| ; NOSFB-LABEL: sdiv8_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srai a1, a0, 63 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: srai a0, a0, 3 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdiv8_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB10_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 7 |
| ; SFB-NEXT: .LBB10_2: |
| ; SFB-NEXT: srai a0, a0, 3 |
| ; SFB-NEXT: ret |
| %res = sdiv i64 %0, 8 |
| ret i64 %res |
| } |
| |
| define i64 @sdivneg8_64(i64 %0) { |
| ; NOSFB-LABEL: sdivneg8_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srai a1, a0, 63 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a0, a0, a1 |
| ; NOSFB-NEXT: srai a0, a0, 3 |
| ; NOSFB-NEXT: neg a0, a0 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sdivneg8_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: bgez a0, .LBB11_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a0, a0, 7 |
| ; SFB-NEXT: .LBB11_2: |
| ; SFB-NEXT: srai a0, a0, 3 |
| ; SFB-NEXT: neg a0, a0 |
| ; SFB-NEXT: ret |
| %res = sdiv i64 %0, -8 |
| ret i64 %res |
| } |
| |
| define signext i32 @srem8_32(i32 signext %0) { |
| ; NOSFB-LABEL: srem8_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: slli a1, a0, 1 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -8 |
| ; NOSFB-NEXT: subw a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: srem8_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB12_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 7 |
| ; SFB-NEXT: .LBB12_2: |
| ; SFB-NEXT: andi a1, a1, -8 |
| ; SFB-NEXT: subw a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i32 %0, 8 |
| ret i32 %res |
| } |
| |
| define signext i32 @sremneg8_32(i32 signext %0) { |
| ; NOSFB-LABEL: sremneg8_32: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: slli a1, a0, 1 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -8 |
| ; NOSFB-NEXT: subw a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sremneg8_32: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB13_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 7 |
| ; SFB-NEXT: .LBB13_2: |
| ; SFB-NEXT: andi a1, a1, -8 |
| ; SFB-NEXT: subw a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i32 %0, -8 |
| ret i32 %res |
| } |
| |
| define i64 @srem8_64(i64 %0) { |
| ; NOSFB-LABEL: srem8_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srai a1, a0, 63 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -8 |
| ; NOSFB-NEXT: sub a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: srem8_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB14_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 7 |
| ; SFB-NEXT: .LBB14_2: |
| ; SFB-NEXT: andi a1, a1, -8 |
| ; SFB-NEXT: sub a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i64 %0, 8 |
| ret i64 %res |
| } |
| |
| define i64 @sremneg8_64(i64 %0) { |
| ; NOSFB-LABEL: sremneg8_64: |
| ; NOSFB: # %bb.0: |
| ; NOSFB-NEXT: srai a1, a0, 63 |
| ; NOSFB-NEXT: srli a1, a1, 61 |
| ; NOSFB-NEXT: add a1, a1, a0 |
| ; NOSFB-NEXT: andi a1, a1, -8 |
| ; NOSFB-NEXT: sub a0, a0, a1 |
| ; NOSFB-NEXT: ret |
| ; |
| ; SFB-LABEL: sremneg8_64: |
| ; SFB: # %bb.0: |
| ; SFB-NEXT: mv a1, a0 |
| ; SFB-NEXT: bgez a0, .LBB15_2 |
| ; SFB-NEXT: # %bb.1: |
| ; SFB-NEXT: addi a1, a0, 7 |
| ; SFB-NEXT: .LBB15_2: |
| ; SFB-NEXT: andi a1, a1, -8 |
| ; SFB-NEXT: sub a0, a0, a1 |
| ; SFB-NEXT: ret |
| %res = srem i64 %0, -8 |
| ret i64 %res |
| } |
| |
| ; Negative tests |
| define i64 @sdiv4096(i64 %0) { |
| ; CHECK-LABEL: sdiv4096: |
| ; CHECK: # %bb.0: |
| ; CHECK-NEXT: srai a1, a0, 63 |
| ; CHECK-NEXT: srli a1, a1, 52 |
| ; CHECK-NEXT: add a0, a0, a1 |
| ; CHECK-NEXT: srai a0, a0, 12 |
| ; CHECK-NEXT: ret |
| %res = sdiv i64 %0, 4096 |
| ret i64 %res |
| } |