| ; 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 < %s | \ | 
 | ; RUN: FileCheck %s | 
 |  | 
 | 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmul.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmul.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmul.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmul.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmul.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fmul.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmul.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fmul.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fadd.d ft2, fa4, fa5 | 
 | ; CHECK-NEXT:    fadd.d ft0, ft0, ft1 | 
 | ; CHECK-NEXT:    fadd.d ft1, ft2, fa6 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fadd.d ft2, fa2, fa1 | 
 | ; CHECK-NEXT:    fcvt.d.w ft3, a0 | 
 | ; CHECK-NEXT:    fcvt.d.w ft4, a1 | 
 | ; CHECK-NEXT:    fmul.d ft3, fa2, ft3 | 
 | ; CHECK-NEXT:    fmul.d ft4, ft4, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft0, ft1, ft0 | 
 | ; CHECK-NEXT:    fmul.d ft1, fa0, ft2 | 
 | ; CHECK-NEXT:    fmul.d ft2, ft4, ft3 | 
 | ; CHECK-NEXT:    fmul.d ft0, ft0, ft1 | 
 | ; CHECK-NEXT:    fmul.d fa0, ft0, ft2 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft0, ft0, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft0, ft0, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, 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 ft0, fa0, fa1, fa2 | 
 | ; CHECK-NEXT:    fmadd.d ft1, fa0, fa1, fa3 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmadd.d ft1, fa0, fa1, fa2 | 
 | ; CHECK-NEXT:    fdiv.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmsub.d ft1, fa0, fa1, fa2 | 
 | ; CHECK-NEXT:    fdiv.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fnmsub.d ft1, fa0, fa1, fa2 | 
 | ; CHECK-NEXT:    fdiv.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fadd.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fsub.d fa0, ft1, ft0 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fsub.d ft1, fa3, fa2 | 
 | ; CHECK-NEXT:    fadd.d fa0, ft1, ft0 | 
 | ; 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:    mulw a0, a0, a1 | 
 | ; CHECK-NEXT:    mulw 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmin.h ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmin.h fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmin.s ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmin.s fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmin.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmin.d fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmax.h ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmax.h fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmax.s ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmax.s fa0, ft0, ft1 | 
 | ; 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 ft0, fa0, fa1 | 
 | ; CHECK-NEXT:    fmax.d ft1, fa2, fa3 | 
 | ; CHECK-NEXT:    fmax.d fa0, ft0, ft1 | 
 | ; 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) |