Files
clang-p2996/llvm/test/CodeGen/RISCV/machine-combiner.ll
Craig Topper 7b0c41841e [RISCV] Move compressible registers to the beginning of the FP allocation order.
We don't have very many compressible FP instructions, just load and store.
These instruction require the FP register to be f8-f15.

This patch changes the FP allocation order to prioritize f10-f15 first.
These are also the FP argument registers. So I allocated them in reverse
order starting at f15 to avoid taking the first argument registers.
This appears to match gcc allocation order.

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D146488
2023-03-27 17:29:28 -07:00

1135 lines
35 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -mattr=+d,+zbb,+zfh -verify-machineinstrs -mcpu=sifive-u74 \
; RUN: -O1 -riscv-enable-machine-combiner=true -riscv-force-machine-combiner-strategy=local < %s | \
; RUN: FileCheck %s --check-prefixes=CHECK,CHECK_LOCAL
; RUN: llc -mtriple=riscv64 -mattr=+d,+zbb,+zfh -verify-machineinstrs -mcpu=sifive-u74 \
; RUN: -O1 -riscv-enable-machine-combiner=true -riscv-force-machine-combiner-strategy=min-instr < %s | \
; RUN: FileCheck %s --check-prefixes=CHECK,CHECK_GLOBAL
define double @test_reassoc_fadd1(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd1:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa2, fa3
; CHECK-NEXT: fadd.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fadd nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fadd2(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd2:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa2, fa3
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %a2, %t0
%t2 = fadd nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fadd3(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd3:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa3, fa2
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fadd nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fadd4(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd4:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa3, fa2
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %a2, %t0
%t2 = fadd nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fmul1(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fmul1:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmul.d fa4, fa2, fa3
; CHECK-NEXT: fmul.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fmul nsz reassoc double %a0, %a1
%t1 = fmul nsz reassoc double %t0, %a2
%t2 = fmul nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fmul2(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fmul2:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmul.d fa4, fa2, fa3
; CHECK-NEXT: fmul.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul nsz reassoc double %a0, %a1
%t1 = fmul nsz reassoc double %a2, %t0
%t2 = fmul nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fmul3(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fmul3:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmul.d fa4, fa3, fa2
; CHECK-NEXT: fmul.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul nsz reassoc double %a0, %a1
%t1 = fmul nsz reassoc double %t0, %a2
%t2 = fmul nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fmul4(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fmul4:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmul.d fa4, fa3, fa2
; CHECK-NEXT: fmul.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul nsz reassoc double %a0, %a1
%t1 = fmul nsz reassoc double %a2, %t0
%t2 = fmul nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_big1(double %a0, double %a1, double %a2, double %a3, double %a4, double %a5, double %a6) {
; CHECK-LABEL: test_reassoc_big1:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa1, fa0, fa1
; CHECK-NEXT: fadd.d fa3, fa2, fa3
; CHECK-NEXT: fadd.d fa5, fa4, fa5
; CHECK-NEXT: fadd.d fa4, fa1, fa3
; CHECK-NEXT: fadd.d fa5, fa5, fa6
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fadd nsz reassoc double %t1, %a3
%t3 = fadd nsz reassoc double %t2, %a4
%t4 = fadd nsz reassoc double %t3, %a5
%t5 = fadd nsz reassoc double %t4, %a6
ret double %t5
}
define double @test_reassoc_big2(double %a0, double %a1, i32 %a2, double %a3, i32 %a4, double %a5) {
; CHECK-LABEL: test_reassoc_big2:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa3, fa2
; CHECK-NEXT: fadd.d fa3, fa2, fa1
; CHECK-NEXT: fcvt.d.w ft0, a0
; CHECK-NEXT: fcvt.d.w ft1, a1
; CHECK-NEXT: fmul.d fa2, fa2, ft0
; CHECK-NEXT: fmul.d fa1, ft1, fa1
; CHECK-NEXT: fsub.d fa5, fa4, fa5
; CHECK-NEXT: fmul.d fa4, fa0, fa3
; CHECK-NEXT: fmul.d fa3, fa1, fa2
; CHECK-NEXT: fmul.d fa5, fa5, fa4
; CHECK-NEXT: fmul.d fa0, fa5, fa3
; CHECK-NEXT: ret
%cvt1 = sitofp i32 %a2 to double
%cvt2 = sitofp i32 %a4 to double
%t5 = fmul nsz reassoc double %a3, %cvt1
%t9 = fmul nsz reassoc double %cvt2, %t5
%t4 = fmul nsz reassoc double %t9, %a1
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %a3, %t0
%t3 = fadd nsz reassoc double %a3, %a1
%t6 = fmul nsz reassoc double %t4, %a0
%t2 = fsub nsz reassoc double %a5, %t1
%t7 = fmul nsz reassoc double %t6, %t3
%t8 = fmul nsz reassoc double %t2, %t7
ret double %t8
}
; Negative test
define double @test_reassoc_fadd_flags_1(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd_flags_1:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa5, fa5, fa2
; CHECK-NEXT: fadd.d fa0, fa5, fa3
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd double %t0, %a2
%t2 = fadd nsz reassoc double %t1, %a3
ret double %t2
}
; Negative test
define double @test_reassoc_fadd_flags_2(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fadd_flags_2:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa5, fa5, fa2
; CHECK-NEXT: fadd.d fa0, fa5, fa3
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fadd double %t1, %a3
ret double %t2
}
define double @test_fmadd1(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_fmadd1:
; CHECK: # %bb.0:
; CHECK-NEXT: fmadd.d fa5, fa0, fa1, fa2
; CHECK-NEXT: fmadd.d fa4, fa0, fa1, fa3
; CHECK-NEXT: fadd.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fmul contract double %a0, %a1
%t1 = fadd contract double %t0, %a2
%t2 = fadd contract double %a3, %t0
%t3 = fadd double %t1, %t2
ret double %t3
}
define double @test_fmadd2(double %a0, double %a1, double %a2) {
; CHECK-LABEL: test_fmadd2:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmadd.d fa4, fa0, fa1, fa2
; CHECK-NEXT: fdiv.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul contract double %a0, %a1
%t1 = fadd contract double %t0, %a2
%t2 = fdiv double %t1, %t0
ret double %t2
}
define double @test_fmsub(double %a0, double %a1, double %a2) {
; CHECK-LABEL: test_fmsub:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fmsub.d fa4, fa0, fa1, fa2
; CHECK-NEXT: fdiv.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul contract double %a0, %a1
%t1 = fsub contract double %t0, %a2
%t2 = fdiv double %t1, %t0
ret double %t2
}
define double @test_fnmsub(double %a0, double %a1, double %a2) {
; CHECK-LABEL: test_fnmsub:
; CHECK: # %bb.0:
; CHECK-NEXT: fmul.d fa5, fa0, fa1
; CHECK-NEXT: fnmsub.d fa4, fa0, fa1, fa2
; CHECK-NEXT: fdiv.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fmul contract double %a0, %a1
%t1 = fsub contract double %a2, %t0
%t2 = fdiv double %t1, %t0
ret double %t2
}
define double @test_reassoc_fsub1(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub1:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa2, fa3
; CHECK-NEXT: fadd.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fsub nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub2(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub2:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa2, fa3
; CHECK-NEXT: fsub.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %t0, %a2
%t2 = fadd nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub3(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub3:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa2, fa3
; CHECK-NEXT: fsub.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %t0, %a2
%t2 = fsub nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub4(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub4:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa2, fa3
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %a2, %t0
%t2 = fsub nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub5(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub5:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa2, fa3
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %a2, %t0
%t2 = fadd nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub6(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub6:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa2, fa3
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %a2, %t0
%t2 = fsub nsz reassoc double %t1, %a3
ret double %t2
}
define double @test_reassoc_fsub7(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub7:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa3, fa2
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %t0, %a2
%t2 = fsub nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fsub8(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub8:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa3, fa2
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %t0, %a2
%t2 = fadd nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fsub9(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub9:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa3, fa2
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %t0, %a2
%t2 = fsub nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fsub10(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub10:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa3, fa2
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fadd nsz reassoc double %a2, %t0
%t2 = fsub nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fsub11(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub11:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fadd.d fa4, fa3, fa2
; CHECK-NEXT: fsub.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %a2, %t0
%t2 = fadd nsz reassoc double %a3, %t1
ret double %t2
}
define double @test_reassoc_fsub12(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_reassoc_fsub12:
; CHECK: # %bb.0:
; CHECK-NEXT: fadd.d fa5, fa0, fa1
; CHECK-NEXT: fsub.d fa4, fa3, fa2
; CHECK-NEXT: fadd.d fa0, fa4, fa5
; CHECK-NEXT: ret
%t0 = fadd nsz reassoc double %a0, %a1
%t1 = fsub nsz reassoc double %a2, %t0
%t2 = fsub nsz reassoc double %a3, %t1
ret double %t2
}
define i8 @test_reassoc_add_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_add_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i8 %a0, %a1
%t1 = add i8 %t0, %a2
%t2 = add i8 %t1, %a3
ret i8 %t2
}
define i16 @test_reassoc_add_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_add_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i16 %a0, %a1
%t1 = add i16 %t0, %a2
%t2 = add i16 %t1, %a3
ret i16 %t2
}
define i32 @test_reassoc_add_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_add_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: addw a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i32 %a0, %a1
%t1 = add i32 %t0, %a2
%t2 = add i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_add_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_add_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i64 %a0, %a1
%t1 = add i64 %t0, %a2
%t2 = add i64 %t1, %a3
ret i64 %t2
}
define i32 @test_reassoc_add_sub_i32_1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i32_1:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: subw a2, a2, a3
; CHECK-NEXT: subw a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i32 %a0, %a1
%t1 = sub i32 %t0, %a2
%t2 = add i32 %t1, %a3
ret i32 %t2
}
define i32 @test_reassoc_add_sub_i32_2(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i32_2:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: subw a2, a2, a3
; CHECK-NEXT: addw a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i32 %a0, %a1
%t1 = add i32 %t0, %a2
%t2 = sub i32 %t1, %a3
ret i32 %t2
}
define i32 @test_reassoc_add_sub_i32_3(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i32_3:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: subw a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i32 %a0, %a1
%t1 = sub i32 %t0, %a2
%t2 = sub i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_add_sub_i64_1(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i64_1:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: sub a2, a2, a3
; CHECK-NEXT: sub a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i64 %a0, %a1
%t1 = sub i64 %t0, %a2
%t2 = add i64 %t1, %a3
ret i64 %t2
}
define i64 @test_reassoc_add_sub_i64_2(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i64_2:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: sub a2, a2, a3
; CHECK-NEXT: add a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i64 %a0, %a1
%t1 = add i64 %t0, %a2
%t2 = sub i64 %t1, %a3
ret i64 %t2
}
define i64 @test_reassoc_add_sub_i64_3(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_add_sub_i64_3:
; CHECK: # %bb.0:
; CHECK-NEXT: add a0, a0, a1
; CHECK-NEXT: add a2, a2, a3
; CHECK-NEXT: sub a0, a0, a2
; CHECK-NEXT: ret
%t0 = add i64 %a0, %a1
%t1 = sub i64 %t0, %a2
%t2 = sub i64 %t1, %a3
ret i64 %t2
}
define i8 @test_reassoc_and_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_and_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: and a0, a0, a1
; CHECK-NEXT: and a2, a2, a3
; CHECK-NEXT: and a0, a0, a2
; CHECK-NEXT: ret
%t0 = and i8 %a0, %a1
%t1 = and i8 %t0, %a2
%t2 = and i8 %t1, %a3
ret i8 %t2
}
define i16 @test_reassoc_and_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_and_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: and a0, a0, a1
; CHECK-NEXT: and a2, a2, a3
; CHECK-NEXT: and a0, a0, a2
; CHECK-NEXT: ret
%t0 = and i16 %a0, %a1
%t1 = and i16 %t0, %a2
%t2 = and i16 %t1, %a3
ret i16 %t2
}
define i32 @test_reassoc_and_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_and_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: and a0, a0, a1
; CHECK-NEXT: and a2, a2, a3
; CHECK-NEXT: and a0, a0, a2
; CHECK-NEXT: ret
%t0 = and i32 %a0, %a1
%t1 = and i32 %t0, %a2
%t2 = and i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_and_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_and_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: and a0, a0, a1
; CHECK-NEXT: and a2, a2, a3
; CHECK-NEXT: and a0, a0, a2
; CHECK-NEXT: ret
%t0 = and i64 %a0, %a1
%t1 = and i64 %t0, %a2
%t2 = and i64 %t1, %a3
ret i64 %t2
}
define i8 @test_reassoc_or_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_or_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: or a0, a0, a1
; CHECK-NEXT: or a2, a2, a3
; CHECK-NEXT: or a0, a0, a2
; CHECK-NEXT: ret
%t0 = or i8 %a0, %a1
%t1 = or i8 %t0, %a2
%t2 = or i8 %t1, %a3
ret i8 %t2
}
define i16 @test_reassoc_or_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_or_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: or a0, a0, a1
; CHECK-NEXT: or a2, a2, a3
; CHECK-NEXT: or a0, a0, a2
; CHECK-NEXT: ret
%t0 = or i16 %a0, %a1
%t1 = or i16 %t0, %a2
%t2 = or i16 %t1, %a3
ret i16 %t2
}
define i32 @test_reassoc_or_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_or_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: or a0, a0, a1
; CHECK-NEXT: or a2, a2, a3
; CHECK-NEXT: or a0, a0, a2
; CHECK-NEXT: ret
%t0 = or i32 %a0, %a1
%t1 = or i32 %t0, %a2
%t2 = or i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_or_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_or_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: or a0, a0, a1
; CHECK-NEXT: or a2, a2, a3
; CHECK-NEXT: or a0, a0, a2
; CHECK-NEXT: ret
%t0 = or i64 %a0, %a1
%t1 = or i64 %t0, %a2
%t2 = or i64 %t1, %a3
ret i64 %t2
}
define i8 @test_reassoc_xor_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_xor_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
; CHECK-NEXT: xor a2, a2, a3
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: ret
%t0 = xor i8 %a0, %a1
%t1 = xor i8 %t0, %a2
%t2 = xor i8 %t1, %a3
ret i8 %t2
}
define i16 @test_reassoc_xor_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_xor_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
; CHECK-NEXT: xor a2, a2, a3
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: ret
%t0 = xor i16 %a0, %a1
%t1 = xor i16 %t0, %a2
%t2 = xor i16 %t1, %a3
ret i16 %t2
}
define i32 @test_reassoc_xor_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_xor_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
; CHECK-NEXT: xor a2, a2, a3
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: ret
%t0 = xor i32 %a0, %a1
%t1 = xor i32 %t0, %a2
%t2 = xor i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_xor_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_xor_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: xor a0, a0, a1
; CHECK-NEXT: xor a2, a2, a3
; CHECK-NEXT: xor a0, a0, a2
; CHECK-NEXT: ret
%t0 = xor i64 %a0, %a1
%t1 = xor i64 %t0, %a2
%t2 = xor i64 %t1, %a3
ret i64 %t2
}
define i8 @test_reassoc_mul_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_mul_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: mul a1, a2, a3
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: ret
%t0 = mul i8 %a0, %a1
%t1 = mul i8 %t0, %a2
%t2 = mul i8 %t1, %a3
ret i8 %t2
}
define i16 @test_reassoc_mul_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_mul_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: mul a1, a2, a3
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: ret
%t0 = mul i16 %a0, %a1
%t1 = mul i16 %t0, %a2
%t2 = mul i16 %t1, %a3
ret i16 %t2
}
define i32 @test_reassoc_mul_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_mul_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: mul a1, a2, a3
; CHECK-NEXT: mulw a0, a0, a1
; CHECK-NEXT: ret
%t0 = mul i32 %a0, %a1
%t1 = mul i32 %t0, %a2
%t2 = mul i32 %t1, %a3
ret i32 %t2
}
define i64 @test_reassoc_mul_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_mul_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: mul a1, a2, a3
; CHECK-NEXT: mul a0, a0, a1
; CHECK-NEXT: ret
%t0 = mul i64 %a0, %a1
%t1 = mul i64 %t0, %a2
%t2 = mul i64 %t1, %a3
ret i64 %t2
}
define i8 @test_reassoc_minu_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_minu_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a3, 255
; CHECK-NEXT: andi a2, a2, 255
; CHECK-NEXT: andi a1, a1, 255
; CHECK-NEXT: andi a0, a0, 255
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: minu a1, a2, a3
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i8 @llvm.umin.i8(i8 %a0, i8 %a1)
%t1 = call i8 @llvm.umin.i8(i8 %t0, i8 %a2)
%t2 = call i8 @llvm.umin.i8(i8 %t1, i8 %a3)
ret i8 %t2
}
define i16 @test_reassoc_minu_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_minu_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: zext.h a3, a3
; CHECK-NEXT: zext.h a2, a2
; CHECK-NEXT: zext.h a1, a1
; CHECK-NEXT: zext.h a0, a0
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: minu a1, a2, a3
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i16 @llvm.umin.i16(i16 %a0, i16 %a1)
%t1 = call i16 @llvm.umin.i16(i16 %t0, i16 %a2)
%t2 = call i16 @llvm.umin.i16(i16 %t1, i16 %a3)
ret i16 %t2
}
define i32 @test_reassoc_minu_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_minu_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.w a3, a3
; CHECK-NEXT: sext.w a2, a2
; CHECK-NEXT: sext.w a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: minu a1, a2, a3
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i32 @llvm.umin.i32(i32 %a0, i32 %a1)
%t1 = call i32 @llvm.umin.i32(i32 %t0, i32 %a2)
%t2 = call i32 @llvm.umin.i32(i32 %t1, i32 %a3)
ret i32 %t2
}
define i64 @test_reassoc_minu_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_minu_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: minu a1, a2, a3
; CHECK-NEXT: minu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i64 @llvm.umin.i64(i64 %a0, i64 %a1)
%t1 = call i64 @llvm.umin.i64(i64 %t0, i64 %a2)
%t2 = call i64 @llvm.umin.i64(i64 %t1, i64 %a3)
ret i64 %t2
}
define i8 @test_reassoc_min_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_min_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.b a3, a3
; CHECK-NEXT: sext.b a2, a2
; CHECK-NEXT: sext.b a1, a1
; CHECK-NEXT: sext.b a0, a0
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: min a1, a2, a3
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i8 @llvm.smin.i8(i8 %a0, i8 %a1)
%t1 = call i8 @llvm.smin.i8(i8 %t0, i8 %a2)
%t2 = call i8 @llvm.smin.i8(i8 %t1, i8 %a3)
ret i8 %t2
}
define i16 @test_reassoc_min_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_min_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.h a3, a3
; CHECK-NEXT: sext.h a2, a2
; CHECK-NEXT: sext.h a1, a1
; CHECK-NEXT: sext.h a0, a0
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: min a1, a2, a3
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i16 @llvm.smin.i16(i16 %a0, i16 %a1)
%t1 = call i16 @llvm.smin.i16(i16 %t0, i16 %a2)
%t2 = call i16 @llvm.smin.i16(i16 %t1, i16 %a3)
ret i16 %t2
}
define i32 @test_reassoc_min_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_min_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.w a3, a3
; CHECK-NEXT: sext.w a2, a2
; CHECK-NEXT: sext.w a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: min a1, a2, a3
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i32 @llvm.smin.i32(i32 %a0, i32 %a1)
%t1 = call i32 @llvm.smin.i32(i32 %t0, i32 %a2)
%t2 = call i32 @llvm.smin.i32(i32 %t1, i32 %a3)
ret i32 %t2
}
define i64 @test_reassoc_min_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_min_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: min a1, a2, a3
; CHECK-NEXT: min a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i64 @llvm.smin.i64(i64 %a0, i64 %a1)
%t1 = call i64 @llvm.smin.i64(i64 %t0, i64 %a2)
%t2 = call i64 @llvm.smin.i64(i64 %t1, i64 %a3)
ret i64 %t2
}
define i8 @test_reassoc_maxu_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_maxu_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: andi a3, a3, 255
; CHECK-NEXT: andi a2, a2, 255
; CHECK-NEXT: andi a1, a1, 255
; CHECK-NEXT: andi a0, a0, 255
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: maxu a1, a2, a3
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i8 @llvm.umax.i8(i8 %a0, i8 %a1)
%t1 = call i8 @llvm.umax.i8(i8 %t0, i8 %a2)
%t2 = call i8 @llvm.umax.i8(i8 %t1, i8 %a3)
ret i8 %t2
}
define i16 @test_reassoc_maxu_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_maxu_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: zext.h a3, a3
; CHECK-NEXT: zext.h a2, a2
; CHECK-NEXT: zext.h a1, a1
; CHECK-NEXT: zext.h a0, a0
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: maxu a1, a2, a3
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i16 @llvm.umax.i16(i16 %a0, i16 %a1)
%t1 = call i16 @llvm.umax.i16(i16 %t0, i16 %a2)
%t2 = call i16 @llvm.umax.i16(i16 %t1, i16 %a3)
ret i16 %t2
}
define i32 @test_reassoc_maxu_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_maxu_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.w a3, a3
; CHECK-NEXT: sext.w a2, a2
; CHECK-NEXT: sext.w a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: maxu a1, a2, a3
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i32 @llvm.umax.i32(i32 %a0, i32 %a1)
%t1 = call i32 @llvm.umax.i32(i32 %t0, i32 %a2)
%t2 = call i32 @llvm.umax.i32(i32 %t1, i32 %a3)
ret i32 %t2
}
define i64 @test_reassoc_maxu_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_maxu_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: maxu a1, a2, a3
; CHECK-NEXT: maxu a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i64 @llvm.umax.i64(i64 %a0, i64 %a1)
%t1 = call i64 @llvm.umax.i64(i64 %t0, i64 %a2)
%t2 = call i64 @llvm.umax.i64(i64 %t1, i64 %a3)
ret i64 %t2
}
define i8 @test_reassoc_max_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
; CHECK-LABEL: test_reassoc_max_i8:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.b a3, a3
; CHECK-NEXT: sext.b a2, a2
; CHECK-NEXT: sext.b a1, a1
; CHECK-NEXT: sext.b a0, a0
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: max a1, a2, a3
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i8 @llvm.smax.i8(i8 %a0, i8 %a1)
%t1 = call i8 @llvm.smax.i8(i8 %t0, i8 %a2)
%t2 = call i8 @llvm.smax.i8(i8 %t1, i8 %a3)
ret i8 %t2
}
define i16 @test_reassoc_max_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
; CHECK-LABEL: test_reassoc_max_i16:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.h a3, a3
; CHECK-NEXT: sext.h a2, a2
; CHECK-NEXT: sext.h a1, a1
; CHECK-NEXT: sext.h a0, a0
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: max a1, a2, a3
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i16 @llvm.smax.i16(i16 %a0, i16 %a1)
%t1 = call i16 @llvm.smax.i16(i16 %t0, i16 %a2)
%t2 = call i16 @llvm.smax.i16(i16 %t1, i16 %a3)
ret i16 %t2
}
define i32 @test_reassoc_max_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
; CHECK-LABEL: test_reassoc_max_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: sext.w a3, a3
; CHECK-NEXT: sext.w a2, a2
; CHECK-NEXT: sext.w a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: max a1, a2, a3
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i32 @llvm.smax.i32(i32 %a0, i32 %a1)
%t1 = call i32 @llvm.smax.i32(i32 %t0, i32 %a2)
%t2 = call i32 @llvm.smax.i32(i32 %t1, i32 %a3)
ret i32 %t2
}
define i64 @test_reassoc_max_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
; CHECK-LABEL: test_reassoc_max_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: max a1, a2, a3
; CHECK-NEXT: max a0, a0, a1
; CHECK-NEXT: ret
%t0 = call i64 @llvm.smax.i64(i64 %a0, i64 %a1)
%t1 = call i64 @llvm.smax.i64(i64 %t0, i64 %a2)
%t2 = call i64 @llvm.smax.i64(i64 %t1, i64 %a3)
ret i64 %t2
}
define half @test_fmin_f16(half %a0, half %a1, half %a2, half %a3) {
; CHECK-LABEL: test_fmin_f16:
; CHECK: # %bb.0:
; CHECK-NEXT: fmin.h fa5, fa0, fa1
; CHECK-NEXT: fmin.h fa4, fa2, fa3
; CHECK-NEXT: fmin.h fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call half @llvm.minnum.f16(half %a0, half %a1)
%t1 = call half @llvm.minnum.f16(half %t0, half %a2)
%t2 = call half @llvm.minnum.f16(half %t1, half %a3)
ret half %t2
}
define float @test_fmin_f32(float %a0, float %a1, float %a2, float %a3) {
; CHECK-LABEL: test_fmin_f32:
; CHECK: # %bb.0:
; CHECK-NEXT: fmin.s fa5, fa0, fa1
; CHECK-NEXT: fmin.s fa4, fa2, fa3
; CHECK-NEXT: fmin.s fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call float @llvm.minnum.f32(float %a0, float %a1)
%t1 = call float @llvm.minnum.f32(float %t0, float %a2)
%t2 = call float @llvm.minnum.f32(float %t1, float %a3)
ret float %t2
}
define double @test_fmin_f64(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_fmin_f64:
; CHECK: # %bb.0:
; CHECK-NEXT: fmin.d fa5, fa0, fa1
; CHECK-NEXT: fmin.d fa4, fa2, fa3
; CHECK-NEXT: fmin.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call double @llvm.minnum.f64(double %a0, double %a1)
%t1 = call double @llvm.minnum.f64(double %t0, double %a2)
%t2 = call double @llvm.minnum.f64(double %t1, double %a3)
ret double %t2
}
define half @test_fmax_f16(half %a0, half %a1, half %a2, half %a3) {
; CHECK-LABEL: test_fmax_f16:
; CHECK: # %bb.0:
; CHECK-NEXT: fmax.h fa5, fa0, fa1
; CHECK-NEXT: fmax.h fa4, fa2, fa3
; CHECK-NEXT: fmax.h fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call half @llvm.maxnum.f16(half %a0, half %a1)
%t1 = call half @llvm.maxnum.f16(half %t0, half %a2)
%t2 = call half @llvm.maxnum.f16(half %t1, half %a3)
ret half %t2
}
define float @test_fmax_f32(float %a0, float %a1, float %a2, float %a3) {
; CHECK-LABEL: test_fmax_f32:
; CHECK: # %bb.0:
; CHECK-NEXT: fmax.s fa5, fa0, fa1
; CHECK-NEXT: fmax.s fa4, fa2, fa3
; CHECK-NEXT: fmax.s fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call float @llvm.maxnum.f32(float %a0, float %a1)
%t1 = call float @llvm.maxnum.f32(float %t0, float %a2)
%t2 = call float @llvm.maxnum.f32(float %t1, float %a3)
ret float %t2
}
define double @test_fmax_f64(double %a0, double %a1, double %a2, double %a3) {
; CHECK-LABEL: test_fmax_f64:
; CHECK: # %bb.0:
; CHECK-NEXT: fmax.d fa5, fa0, fa1
; CHECK-NEXT: fmax.d fa4, fa2, fa3
; CHECK-NEXT: fmax.d fa0, fa5, fa4
; CHECK-NEXT: ret
%t0 = call double @llvm.maxnum.f64(double %a0, double %a1)
%t1 = call double @llvm.maxnum.f64(double %t0, double %a2)
%t2 = call double @llvm.maxnum.f64(double %t1, double %a3)
ret double %t2
}
declare i8 @llvm.umin.i8(i8 %a, i8 %b)
declare i16 @llvm.umin.i16(i16 %a, i16 %b)
declare i32 @llvm.umin.i32(i32 %a, i32 %b)
declare i64 @llvm.umin.i64(i64 %a, i64 %b)
declare i8 @llvm.smin.i8(i8 %a, i8 %b)
declare i16 @llvm.smin.i16(i16 %a, i16 %b)
declare i32 @llvm.smin.i32(i32 %a, i32 %b)
declare i64 @llvm.smin.i64(i64 %a, i64 %b)
declare i8 @llvm.umax.i8(i8 %a, i8 %b)
declare i16 @llvm.umax.i16(i16 %a, i16 %b)
declare i32 @llvm.umax.i32(i32 %a, i32 %b)
declare i64 @llvm.umax.i64(i64 %a, i64 %b)
declare i8 @llvm.smax.i8(i8 %a, i8 %b)
declare i16 @llvm.smax.i16(i16 %a, i16 %b)
declare i32 @llvm.smax.i32(i32 %a, i32 %b)
declare i64 @llvm.smax.i64(i64 %a, i64 %b)
declare half @llvm.minnum.f16(half, half)
declare float @llvm.minnum.f32(float, float)
declare double @llvm.minnum.f64(double, double)
declare half @llvm.maxnum.f16(half, half)
declare float @llvm.maxnum.f32(float, float)
declare double @llvm.maxnum.f64(double, double)
define double @test_fmadd_strategy(double %a0, double %a1, double %a2, double %a3, i64 %flag) {
; CHECK_LOCAL-LABEL: test_fmadd_strategy:
; CHECK_LOCAL: # %bb.0: # %entry
; CHECK_LOCAL-NEXT: fmv.d fa5, fa0
; CHECK_LOCAL-NEXT: fsub.d fa4, fa0, fa1
; CHECK_LOCAL-NEXT: fmul.d fa0, fa4, fa2
; CHECK_LOCAL-NEXT: andi a0, a0, 1
; CHECK_LOCAL-NEXT: beqz a0, .LBB76_2
; CHECK_LOCAL-NEXT: # %bb.1: # %entry
; CHECK_LOCAL-NEXT: fmul.d fa4, fa5, fa1
; CHECK_LOCAL-NEXT: fmadd.d fa5, fa5, fa1, fa0
; CHECK_LOCAL-NEXT: fsub.d fa0, fa5, fa4
; CHECK_LOCAL-NEXT: .LBB76_2: # %entry
; CHECK_LOCAL-NEXT: ret
;
; CHECK_GLOBAL-LABEL: test_fmadd_strategy:
; CHECK_GLOBAL: # %bb.0: # %entry
; CHECK_GLOBAL-NEXT: fmv.d fa5, fa0
; CHECK_GLOBAL-NEXT: fsub.d fa4, fa0, fa1
; CHECK_GLOBAL-NEXT: fmul.d fa0, fa4, fa2
; CHECK_GLOBAL-NEXT: andi a0, a0, 1
; CHECK_GLOBAL-NEXT: beqz a0, .LBB76_2
; CHECK_GLOBAL-NEXT: # %bb.1: # %entry
; CHECK_GLOBAL-NEXT: fmul.d fa5, fa5, fa1
; CHECK_GLOBAL-NEXT: fadd.d fa4, fa5, fa0
; CHECK_GLOBAL-NEXT: fsub.d fa0, fa4, fa5
; CHECK_GLOBAL-NEXT: .LBB76_2: # %entry
; CHECK_GLOBAL-NEXT: ret
entry:
%sub = fsub contract double %a0, %a1
%mul = fmul contract double %sub, %a2
%and = and i64 %flag, 1
%tobool.not = icmp eq i64 %and, 0
%mul2 = fmul contract double %a0, %a1
%add = fadd contract double %mul2, %mul
%sub3 = fsub contract double %add, %mul2
%retval.0 = select i1 %tobool.not, double %mul, double %sub3
ret double %retval.0
}