| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: llc < %s -verify-machineinstrs -mtriple=riscv64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,64-BITS |
| ; RUN: llc < %s -verify-machineinstrs -mtriple=riscv32-unknown-unknown | FileCheck %s --check-prefixes=CHECK,32-BITS |
| |
| define i32 @skip(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="skip" { |
| ; 64-BITS-LABEL: skip: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: skip: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @used_gpr_arg(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="used-gpr-arg" { |
| ; 64-BITS-LABEL: used_gpr_arg: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used_gpr_arg: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @used_gpr(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="used-gpr" { |
| ; 64-BITS-LABEL: used_gpr: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used_gpr: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @used_arg(i32 noundef %a, i32 noundef %b, i32 noundef %c, i32 noundef %d) #0 "zero-call-used-regs"="used-arg" { |
| ; 64-BITS-LABEL: used_arg: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used_arg: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @used(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="used" { |
| ; 64-BITS-LABEL: used: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @all_gpr_arg(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="all-gpr-arg" { |
| ; 64-BITS-LABEL: all_gpr_arg: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: li a3, 0 |
| ; 64-BITS-NEXT: li a4, 0 |
| ; 64-BITS-NEXT: li a5, 0 |
| ; 64-BITS-NEXT: li a6, 0 |
| ; 64-BITS-NEXT: li a7, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: all_gpr_arg: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: li a3, 0 |
| ; 32-BITS-NEXT: li a4, 0 |
| ; 32-BITS-NEXT: li a5, 0 |
| ; 32-BITS-NEXT: li a6, 0 |
| ; 32-BITS-NEXT: li a7, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define i32 @all_gpr(i32 noundef %a, i32 noundef %b, i32 noundef %c) #0 "zero-call-used-regs"="all-gpr" { |
| ; 64-BITS-LABEL: all_gpr: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: mulw a0, a1, a0 |
| ; 64-BITS-NEXT: or a0, a0, a2 |
| ; 64-BITS-NEXT: li t0, 0 |
| ; 64-BITS-NEXT: li t1, 0 |
| ; 64-BITS-NEXT: li t2, 0 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: li a3, 0 |
| ; 64-BITS-NEXT: li a4, 0 |
| ; 64-BITS-NEXT: li a5, 0 |
| ; 64-BITS-NEXT: li a6, 0 |
| ; 64-BITS-NEXT: li a7, 0 |
| ; 64-BITS-NEXT: li t3, 0 |
| ; 64-BITS-NEXT: li t4, 0 |
| ; 64-BITS-NEXT: li t5, 0 |
| ; 64-BITS-NEXT: li t6, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: all_gpr: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: mul a0, a1, a0 |
| ; 32-BITS-NEXT: or a0, a0, a2 |
| ; 32-BITS-NEXT: li t0, 0 |
| ; 32-BITS-NEXT: li t1, 0 |
| ; 32-BITS-NEXT: li t2, 0 |
| ; 32-BITS-NEXT: li a1, 0 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: li a3, 0 |
| ; 32-BITS-NEXT: li a4, 0 |
| ; 32-BITS-NEXT: li a5, 0 |
| ; 32-BITS-NEXT: li a6, 0 |
| ; 32-BITS-NEXT: li a7, 0 |
| ; 32-BITS-NEXT: li t3, 0 |
| ; 32-BITS-NEXT: li t4, 0 |
| ; 32-BITS-NEXT: li t5, 0 |
| ; 32-BITS-NEXT: li t6, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %mul = mul nsw i32 %b, %a |
| %or = or i32 %mul, %c |
| ret i32 %or |
| } |
| |
| define double @skip_float(double noundef %a, float noundef %b) #0 "zero-call-used-regs"="skip" { |
| ; CHECK-LABEL: skip_float: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fcvt.d.s fa5, fa1 |
| ; CHECK-NEXT: fmul.d fa0, fa5, fa0 |
| ; CHECK-NEXT: ret |
| |
| entry: |
| %conv = fpext float %b to double |
| %mul = fmul double %conv, %a |
| ret double %mul |
| } |
| |
| define double @used_gpr_arg_float(double noundef %a, float noundef %b) #0 "zero-call-used-regs"="used-gpr-arg" { |
| ; CHECK-LABEL: used_gpr_arg_float: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fcvt.d.s fa5, fa1 |
| ; CHECK-NEXT: fmul.d fa0, fa5, fa0 |
| ; CHECK-NEXT: ret |
| |
| entry: |
| %conv = fpext float %b to double |
| %mul = fmul double %conv, %a |
| ret double %mul |
| } |
| |
| define double @used_gpr_float(double noundef %a, float noundef %b) #0 "zero-call-used-regs"="used-gpr" { |
| ; CHECK-LABEL: used_gpr_float: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fcvt.d.s fa5, fa1 |
| ; CHECK-NEXT: fmul.d fa0, fa5, fa0 |
| ; CHECK-NEXT: ret |
| |
| entry: |
| %conv = fpext float %b to double |
| %mul = fmul double %conv, %a |
| ret double %mul |
| } |
| |
| define double @all_gpr_arg_float(double noundef %a, float noundef %b) #0 "zero-call-used-regs"="all-gpr-arg" { |
| ; CHECK-LABEL: all_gpr_arg_float: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fcvt.d.s fa5, fa1 |
| ; CHECK-NEXT: fmul.d fa0, fa5, fa0 |
| ; CHECK-NEXT: li a0, 0 |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: li a2, 0 |
| ; CHECK-NEXT: li a3, 0 |
| ; CHECK-NEXT: li a4, 0 |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: li a6, 0 |
| ; CHECK-NEXT: li a7, 0 |
| ; CHECK-NEXT: ret |
| |
| entry: |
| %conv = fpext float %b to double |
| %mul = fmul double %conv, %a |
| ret double %mul |
| } |
| |
| define double @all_gpr_float(double noundef %a, float noundef %b) #0 "zero-call-used-regs"="all-gpr" { |
| ; CHECK-LABEL: all_gpr_float: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: fcvt.d.s fa5, fa1 |
| ; CHECK-NEXT: fmul.d fa0, fa5, fa0 |
| ; CHECK-NEXT: li t0, 0 |
| ; CHECK-NEXT: li t1, 0 |
| ; CHECK-NEXT: li t2, 0 |
| ; CHECK-NEXT: li a0, 0 |
| ; CHECK-NEXT: li a1, 0 |
| ; CHECK-NEXT: li a2, 0 |
| ; CHECK-NEXT: li a3, 0 |
| ; CHECK-NEXT: li a4, 0 |
| ; CHECK-NEXT: li a5, 0 |
| ; CHECK-NEXT: li a6, 0 |
| ; CHECK-NEXT: li a7, 0 |
| ; CHECK-NEXT: li t3, 0 |
| ; CHECK-NEXT: li t4, 0 |
| ; CHECK-NEXT: li t5, 0 |
| ; CHECK-NEXT: li t6, 0 |
| ; CHECK-NEXT: ret |
| |
| entry: |
| %conv = fpext float %b to double |
| %mul = fmul double %conv, %a |
| ret double %mul |
| } |
| |
| define double @used_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used" { |
| ; 64-BITS-LABEL: used_zdinx: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: fmul.d a0, a0, a1 |
| ; 64-BITS-NEXT: fcvt.d.s a1, a2 |
| ; 64-BITS-NEXT: fmul.d a0, a0, a1 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used_zdinx: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: fmul.d a0, a0, a2 |
| ; 32-BITS-NEXT: fcvt.d.s a2, a4 |
| ; 32-BITS-NEXT: fmul.d a0, a0, a2 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: li a3, 0 |
| ; 32-BITS-NEXT: li a4, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %conv = fpext float %c to double |
| %mul1 = fmul double %a, %b |
| %mul2 = fmul double %mul1, %conv |
| ret double %mul2 |
| } |
| |
| define double @used_arg_zdinx(double noundef %a, double noundef %b, float noundef %c) #1 "zero-call-used-regs"="used-arg" { |
| ; 64-BITS-LABEL: used_arg_zdinx: |
| ; 64-BITS: # %bb.0: # %entry |
| ; 64-BITS-NEXT: fmul.d a0, a0, a1 |
| ; 64-BITS-NEXT: fcvt.d.s a1, a2 |
| ; 64-BITS-NEXT: fmul.d a0, a0, a1 |
| ; 64-BITS-NEXT: li a1, 0 |
| ; 64-BITS-NEXT: li a2, 0 |
| ; 64-BITS-NEXT: ret |
| ; |
| ; 32-BITS-LABEL: used_arg_zdinx: |
| ; 32-BITS: # %bb.0: # %entry |
| ; 32-BITS-NEXT: fmul.d a0, a0, a2 |
| ; 32-BITS-NEXT: fcvt.d.s a2, a4 |
| ; 32-BITS-NEXT: fmul.d a0, a0, a2 |
| ; 32-BITS-NEXT: li a2, 0 |
| ; 32-BITS-NEXT: li a3, 0 |
| ; 32-BITS-NEXT: li a4, 0 |
| ; 32-BITS-NEXT: ret |
| |
| entry: |
| %conv = fpext float %c to double |
| %mul1 = fmul double %a, %b |
| %mul2 = fmul double %mul1, %conv |
| ret double %mul2 |
| } |
| |
| attributes #0 = { "target-cpu"="generic" "target-features"="+m,+f,+d" } |
| attributes #1 = { "target-cpu"="generic" "target-features"="+m,+zdinx" } |