Replacing D143754. Right now the LiveRangeSplitting during register allocation uses TargetOpcode::COPY instruction for splitting. For AMDGPU target that creates a problem as we have both vector and scalar copies. Vector copies perform a copy over a vector register but only on the lanes(threads) that are active. This is mostly sufficient however we do run into cases when we have to copy the entire vector register and not just active lane data. One major place where we need that is live range splitting. Allowing targets to use their own copy instructions(if defined) will provide a lot of flexibility and ease to lower these pseudo instructions to correct MIR. - Introduce getTargetCopyOpcode() virtual function and use if to generate copy in Live range splitting. - Replace necessary MI.isCopy() checks with TII.isCopyInstr() in register allocator pipeline. Reviewed By: arsenm, cdevadas, kparzysz Differential Revision: https://reviews.llvm.org/D150388
586 lines
14 KiB
LLVM
586 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefixes=32
|
|
; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefixes=32
|
|
; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefixes=32R6
|
|
; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP
|
|
; RUN: llc -march=mips -mcpu=mips64 -target-abi n64 < %s | FileCheck %s -check-prefixes=64
|
|
; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s | FileCheck %s -check-prefixes=64
|
|
; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s | FileCheck %s -check-prefixes=64R6
|
|
; RUN: llc -march=mips -mattr=mips16 < %s | FileCheck %s -check-prefixes=16
|
|
|
|
define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
|
|
; 32-LABEL: madd1:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: sra $1, $6, 31
|
|
; 32-NEXT: mtlo $6
|
|
; 32-NEXT: mthi $1
|
|
; 32-NEXT: madd $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: madd1:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: addu $3, $1, $6
|
|
; 32R6-NEXT: sltu $1, $3, $1
|
|
; 32R6-NEXT: muh $2, $5, $4
|
|
; 32R6-NEXT: sra $4, $6, 31
|
|
; 32R6-NEXT: addu $2, $2, $4
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: addu $2, $2, $1
|
|
;
|
|
; DSP-LABEL: madd1:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: sra $1, $6, 31
|
|
; DSP-NEXT: mtlo $6, $ac0
|
|
; DSP-NEXT: mthi $1, $ac0
|
|
; DSP-NEXT: madd $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: madd1:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $4, $4, 0
|
|
; 64-NEXT: sll $5, $5, 0
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: sll $6, $6, 0
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 64R6-LABEL: madd1:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $4, $4, 0
|
|
; 64R6-NEXT: sll $5, $5, 0
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: sll $6, $6, 0
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 16-LABEL: madd1:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $3
|
|
; 16-NEXT: sra $4, $6, 31
|
|
; 16-NEXT: addu $4, $3, $4
|
|
; 16-NEXT: addu $3, $2, $6
|
|
; 16-NEXT: sltu $3, $2
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: addu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = sext i32 %a to i64
|
|
%conv2 = sext i32 %b to i64
|
|
%mul = mul nsw i64 %conv2, %conv
|
|
%conv4 = sext i32 %c to i64
|
|
%add = add nsw i64 %mul, %conv4
|
|
ret i64 %add
|
|
}
|
|
|
|
define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
|
|
; 32-LABEL: madd2:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: addiu $1, $zero, 0
|
|
; 32-NEXT: mtlo $6
|
|
; 32-NEXT: mthi $1
|
|
; 32-NEXT: maddu $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: madd2:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: addu $3, $1, $6
|
|
; 32R6-NEXT: sltu $1, $3, $1
|
|
; 32R6-NEXT: muhu $2, $5, $4
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: addu $2, $2, $1
|
|
;
|
|
; DSP-LABEL: madd2:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: addiu $1, $zero, 0
|
|
; DSP-NEXT: mtlo $6, $ac0
|
|
; DSP-NEXT: mthi $1, $ac0
|
|
; DSP-NEXT: maddu $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: madd2:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 64R6-LABEL: madd2:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 16-LABEL: madd2:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: multu $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $4
|
|
; 16-NEXT: addu $3, $2, $6
|
|
; 16-NEXT: sltu $3, $2
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: addu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = zext i32 %a to i64
|
|
%conv2 = zext i32 %b to i64
|
|
%mul = mul nsw i64 %conv2, %conv
|
|
%conv4 = zext i32 %c to i64
|
|
%add = add nsw i64 %mul, %conv4
|
|
ret i64 %add
|
|
}
|
|
|
|
define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
|
|
; 32-LABEL: madd3:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: mtlo $7
|
|
; 32-NEXT: mthi $6
|
|
; 32-NEXT: madd $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: madd3:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: addu $3, $1, $7
|
|
; 32R6-NEXT: sltu $1, $3, $1
|
|
; 32R6-NEXT: muh $2, $5, $4
|
|
; 32R6-NEXT: addu $2, $2, $6
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: addu $2, $2, $1
|
|
;
|
|
; DSP-LABEL: madd3:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: mtlo $7, $ac0
|
|
; DSP-NEXT: mthi $6, $ac0
|
|
; DSP-NEXT: madd $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: madd3:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $4, $4, 0
|
|
; 64-NEXT: sll $5, $5, 0
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 64R6-LABEL: madd3:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $4, $4, 0
|
|
; 64R6-NEXT: sll $5, $5, 0
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: daddu $2, $1, $6
|
|
;
|
|
; 16-LABEL: madd3:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $3
|
|
; 16-NEXT: addu $4, $3, $6
|
|
; 16-NEXT: addu $3, $2, $7
|
|
; 16-NEXT: sltu $3, $2
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: addu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = sext i32 %a to i64
|
|
%conv2 = sext i32 %b to i64
|
|
%mul = mul nsw i64 %conv2, %conv
|
|
%add = add nsw i64 %mul, %c
|
|
ret i64 %add
|
|
}
|
|
|
|
define i32 @madd4(i32 %a, i32 %b, i32 %c) {
|
|
; 32-LABEL: madd4:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: mul $1, $4, $5
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: addu $2, $6, $1
|
|
;
|
|
; 32R6-LABEL: madd4:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $4, $5
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: addu $2, $6, $1
|
|
;
|
|
; DSP-LABEL: madd4:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: mul $1, $4, $5
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: addu $2, $6, $1
|
|
;
|
|
; 64-LABEL: madd4:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $1, $5, 0
|
|
; 64-NEXT: sll $2, $4, 0
|
|
; 64-NEXT: mul $1, $2, $1
|
|
; 64-NEXT: sll $2, $6, 0
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: addu $2, $2, $1
|
|
;
|
|
; 64R6-LABEL: madd4:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $1, $5, 0
|
|
; 64R6-NEXT: sll $2, $4, 0
|
|
; 64R6-NEXT: mul $1, $2, $1
|
|
; 64R6-NEXT: sll $2, $6, 0
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: addu $2, $2, $1
|
|
;
|
|
; 16-LABEL: madd4:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $4, $5
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: addu $2, $6, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%mul = mul nsw i32 %a, %b
|
|
%add = add nsw i32 %c, %mul
|
|
|
|
ret i32 %add
|
|
}
|
|
|
|
define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
|
|
; 32-LABEL: msub1:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: sra $1, $6, 31
|
|
; 32-NEXT: mtlo $6
|
|
; 32-NEXT: mthi $1
|
|
; 32-NEXT: msub $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: msub1:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: sltu $2, $6, $1
|
|
; 32R6-NEXT: muh $3, $5, $4
|
|
; 32R6-NEXT: sra $4, $6, 31
|
|
; 32R6-NEXT: subu $3, $4, $3
|
|
; 32R6-NEXT: subu $2, $3, $2
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: subu $3, $6, $1
|
|
;
|
|
; DSP-LABEL: msub1:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: sra $1, $6, 31
|
|
; DSP-NEXT: mtlo $6, $ac0
|
|
; DSP-NEXT: mthi $1, $ac0
|
|
; DSP-NEXT: msub $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: msub1:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $4, $4, 0
|
|
; 64-NEXT: sll $5, $5, 0
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: sll $6, $6, 0
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 64R6-LABEL: msub1:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $4, $4, 0
|
|
; 64R6-NEXT: sll $5, $5, 0
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: sll $6, $6, 0
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 16-LABEL: msub1:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $4
|
|
; 16-NEXT: subu $3, $6, $2
|
|
; 16-NEXT: sltu $6, $2
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: sra $5, $6, 31
|
|
; 16-NEXT: subu $4, $5, $4
|
|
; 16-NEXT: subu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = sext i32 %c to i64
|
|
%conv2 = sext i32 %a to i64
|
|
%conv4 = sext i32 %b to i64
|
|
%mul = mul nsw i64 %conv4, %conv2
|
|
%sub = sub nsw i64 %conv, %mul
|
|
ret i64 %sub
|
|
}
|
|
|
|
define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
|
|
; 32-LABEL: msub2:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: addiu $1, $zero, 0
|
|
; 32-NEXT: mtlo $6
|
|
; 32-NEXT: mthi $1
|
|
; 32-NEXT: msubu $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: msub2:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: muhu $1, $5, $4
|
|
; 32R6-NEXT: mul $3, $5, $4
|
|
; 32R6-NEXT: sltu $2, $6, $3
|
|
; 32R6-NEXT: addu $1, $1, $2
|
|
; 32R6-NEXT: negu $2, $1
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: subu $3, $6, $3
|
|
;
|
|
; DSP-LABEL: msub2:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: addiu $1, $zero, 0
|
|
; DSP-NEXT: mtlo $6, $ac0
|
|
; DSP-NEXT: mthi $1, $ac0
|
|
; DSP-NEXT: msubu $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: msub2:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 64R6-LABEL: msub2:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 16-LABEL: msub2:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: multu $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $3
|
|
; 16-NEXT: sltu $6, $2
|
|
; 16-NEXT: move $4, $24
|
|
; 16-NEXT: addu $4, $3, $4
|
|
; 16-NEXT: subu $3, $6, $2
|
|
; 16-NEXT: neg $2, $4
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = zext i32 %c to i64
|
|
%conv2 = zext i32 %a to i64
|
|
%conv4 = zext i32 %b to i64
|
|
%mul = mul nsw i64 %conv4, %conv2
|
|
%sub = sub nsw i64 %conv, %mul
|
|
ret i64 %sub
|
|
}
|
|
|
|
define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
|
|
; 32-LABEL: msub3:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: mtlo $7
|
|
; 32-NEXT: mthi $6
|
|
; 32-NEXT: msub $5, $4
|
|
; 32-NEXT: mfhi $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: mflo $3
|
|
;
|
|
; 32R6-LABEL: msub3:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: sltu $2, $7, $1
|
|
; 32R6-NEXT: muh $3, $5, $4
|
|
; 32R6-NEXT: subu $3, $6, $3
|
|
; 32R6-NEXT: subu $2, $3, $2
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: subu $3, $7, $1
|
|
;
|
|
; DSP-LABEL: msub3:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: mtlo $7, $ac0
|
|
; DSP-NEXT: mthi $6, $ac0
|
|
; DSP-NEXT: msub $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $2, $ac0
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
;
|
|
; 64-LABEL: msub3:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $4, $4, 0
|
|
; 64-NEXT: sll $5, $5, 0
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 64R6-LABEL: msub3:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $4, $4, 0
|
|
; 64R6-NEXT: sll $5, $5, 0
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: dsubu $2, $6, $1
|
|
;
|
|
; 16-LABEL: msub3:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $4
|
|
; 16-NEXT: subu $3, $7, $2
|
|
; 16-NEXT: sltu $7, $2
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: subu $4, $6, $4
|
|
; 16-NEXT: subu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = sext i32 %a to i64
|
|
%conv3 = sext i32 %b to i64
|
|
%mul = mul nsw i64 %conv3, %conv
|
|
%sub = sub nsw i64 %c, %mul
|
|
ret i64 %sub
|
|
}
|
|
|
|
define i32 @msub4(i32 %a, i32 %b, i32 %c) {
|
|
; 32-LABEL: msub4:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: mul $1, $4, $5
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: subu $2, $6, $1
|
|
;
|
|
; 32R6-LABEL: msub4:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $4, $5
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: subu $2, $6, $1
|
|
;
|
|
; DSP-LABEL: msub4:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: mul $1, $4, $5
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: subu $2, $6, $1
|
|
;
|
|
; 64-LABEL: msub4:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $1, $5, 0
|
|
; 64-NEXT: sll $2, $4, 0
|
|
; 64-NEXT: mul $1, $2, $1
|
|
; 64-NEXT: sll $2, $6, 0
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: subu $2, $2, $1
|
|
;
|
|
; 64R6-LABEL: msub4:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $1, $5, 0
|
|
; 64R6-NEXT: sll $2, $4, 0
|
|
; 64R6-NEXT: mul $1, $2, $1
|
|
; 64R6-NEXT: sll $2, $6, 0
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: subu $2, $2, $1
|
|
;
|
|
; 16-LABEL: msub4:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $4, $5
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: subu $2, $6, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%mul = mul nsw i32 %a, %b
|
|
%sub = sub nsw i32 %c, %mul
|
|
|
|
ret i32 %sub
|
|
}
|
|
|
|
define i64 @msub5(i32 %a, i32 %b, i32 %c) {
|
|
; 32-LABEL: msub5:
|
|
; 32: # %bb.0: # %entry
|
|
; 32-NEXT: mult $5, $4
|
|
; 32-NEXT: mfhi $1
|
|
; 32-NEXT: mflo $3
|
|
; 32-NEXT: sltu $2, $3, $6
|
|
; 32-NEXT: sra $4, $6, 31
|
|
; 32-NEXT: subu $1, $1, $4
|
|
; 32-NEXT: subu $2, $1, $2
|
|
; 32-NEXT: jr $ra
|
|
; 32-NEXT: subu $3, $3, $6
|
|
;
|
|
; 32R6-LABEL: msub5:
|
|
; 32R6: # %bb.0: # %entry
|
|
; 32R6-NEXT: mul $1, $5, $4
|
|
; 32R6-NEXT: sltu $2, $1, $6
|
|
; 32R6-NEXT: muh $3, $5, $4
|
|
; 32R6-NEXT: sra $4, $6, 31
|
|
; 32R6-NEXT: subu $3, $3, $4
|
|
; 32R6-NEXT: subu $2, $3, $2
|
|
; 32R6-NEXT: jr $ra
|
|
; 32R6-NEXT: subu $3, $1, $6
|
|
;
|
|
; DSP-LABEL: msub5:
|
|
; DSP: # %bb.0: # %entry
|
|
; DSP-NEXT: mult $ac0, $5, $4
|
|
; DSP-NEXT: mfhi $1, $ac0
|
|
; DSP-NEXT: mflo $3, $ac0
|
|
; DSP-NEXT: sltu $2, $3, $6
|
|
; DSP-NEXT: sra $4, $6, 31
|
|
; DSP-NEXT: subu $1, $1, $4
|
|
; DSP-NEXT: subu $2, $1, $2
|
|
; DSP-NEXT: jr $ra
|
|
; DSP-NEXT: subu $3, $3, $6
|
|
;
|
|
; 64-LABEL: msub5:
|
|
; 64: # %bb.0: # %entry
|
|
; 64-NEXT: sll $4, $4, 0
|
|
; 64-NEXT: sll $5, $5, 0
|
|
; 64-NEXT: dmult $5, $4
|
|
; 64-NEXT: mflo $1
|
|
; 64-NEXT: sll $6, $6, 0
|
|
; 64-NEXT: jr $ra
|
|
; 64-NEXT: dsubu $2, $1, $6
|
|
;
|
|
; 64R6-LABEL: msub5:
|
|
; 64R6: # %bb.0: # %entry
|
|
; 64R6-NEXT: sll $4, $4, 0
|
|
; 64R6-NEXT: sll $5, $5, 0
|
|
; 64R6-NEXT: dmul $1, $5, $4
|
|
; 64R6-NEXT: sll $6, $6, 0
|
|
; 64R6-NEXT: jr $ra
|
|
; 64R6-NEXT: dsubu $2, $1, $6
|
|
;
|
|
; 16-LABEL: msub5:
|
|
; 16: # %bb.0: # %entry
|
|
; 16-NEXT: mult $5, $4
|
|
; 16-NEXT: mflo $2
|
|
; 16-NEXT: mfhi $4
|
|
; 16-NEXT: subu $3, $2, $6
|
|
; 16-NEXT: sltu $2, $6
|
|
; 16-NEXT: move $2, $24
|
|
; 16-NEXT: sra $5, $6, 31
|
|
; 16-NEXT: subu $4, $4, $5
|
|
; 16-NEXT: subu $2, $4, $2
|
|
; 16-NEXT: jrc $ra
|
|
entry:
|
|
%conv = sext i32 %a to i64
|
|
%conv3 = sext i32 %b to i64
|
|
%conv4 = sext i32 %c to i64
|
|
%mul = mul nsw i64 %conv3, %conv
|
|
%sub = sub nsw i64 %mul, %conv4
|
|
ret i64 %sub
|
|
}
|