; 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 a1, a1, 255
; CHECK-NEXT: andi a0, a0, 255
; CHECK-NEXT: andi a2, a2, 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 a1, a1
; CHECK-NEXT: zext.h a0, a0
; CHECK-NEXT: zext.h a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: sext.w a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.b a0, a0
; CHECK-NEXT: sext.b a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.h a0, a0
; CHECK-NEXT: sext.h a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: sext.w a2, a2
; 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 a1, a1, 255
; CHECK-NEXT: andi a0, a0, 255
; CHECK-NEXT: andi a2, a2, 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 a1, a1
; CHECK-NEXT: zext.h a0, a0
; CHECK-NEXT: zext.h a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: sext.w a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.b a0, a0
; CHECK-NEXT: sext.b a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.h a0, a0
; CHECK-NEXT: sext.h a2, a2
; 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 a1, a1
; CHECK-NEXT: sext.w a0, a0
; CHECK-NEXT: sext.w a2, a2
; 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: fsub.d fa4, fa0, fa1
; CHECK_LOCAL-NEXT: andi a0, a0, 1
; CHECK_LOCAL-NEXT: fmv.d fa5, fa0
; CHECK_LOCAL-NEXT: fmul.d fa0, fa4, fa2
; 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: fsub.d fa4, fa0, fa1
; CHECK_GLOBAL-NEXT: andi a0, a0, 1
; CHECK_GLOBAL-NEXT: fmv.d fa5, fa0
; CHECK_GLOBAL-NEXT: fmul.d fa0, fa4, fa2
; 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
}