1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs < %s \ 3; RUN: | FileCheck -check-prefix=RV32IF %s 4 5define float @flw(float *%a) nounwind { 6; RV32IF-LABEL: flw: 7; RV32IF: # %bb.0: 8; RV32IF-NEXT: flw ft0, 12(a0) 9; RV32IF-NEXT: flw ft1, 0(a0) 10; RV32IF-NEXT: fadd.s ft0, ft1, ft0 11; RV32IF-NEXT: fmv.x.w a0, ft0 12; RV32IF-NEXT: ret 13 %1 = load float, float* %a 14 %2 = getelementptr float, float* %a, i32 3 15 %3 = load float, float* %2 16; Use both loaded values in an FP op to ensure an flw is used, even for the 17; soft float ABI 18 %4 = fadd float %1, %3 19 ret float %4 20} 21 22define void @fsw(float *%a, float %b, float %c) nounwind { 23; Use %b and %c in an FP op to ensure floating point registers are used, even 24; for the soft float ABI 25; RV32IF-LABEL: fsw: 26; RV32IF: # %bb.0: 27; RV32IF-NEXT: fmv.w.x ft0, a2 28; RV32IF-NEXT: fmv.w.x ft1, a1 29; RV32IF-NEXT: fadd.s ft0, ft1, ft0 30; RV32IF-NEXT: fsw ft0, 32(a0) 31; RV32IF-NEXT: fsw ft0, 0(a0) 32; RV32IF-NEXT: ret 33 %1 = fadd float %b, %c 34 store float %1, float* %a 35 %2 = getelementptr float, float* %a, i32 8 36 store float %1, float* %2 37 ret void 38} 39 40; Check load and store to a global 41@G = global float 0.0 42 43define float @flw_fsw_global(float %a, float %b) nounwind { 44; Use %a and %b in an FP op to ensure floating point registers are used, even 45; for the soft float ABI 46; RV32IF-LABEL: flw_fsw_global: 47; RV32IF: # %bb.0: 48; RV32IF-NEXT: fmv.w.x ft0, a1 49; RV32IF-NEXT: fmv.w.x ft1, a0 50; RV32IF-NEXT: fadd.s ft0, ft1, ft0 51; RV32IF-NEXT: lui a0, %hi(G) 52; RV32IF-NEXT: flw ft1, %lo(G)(a0) 53; RV32IF-NEXT: fsw ft0, %lo(G)(a0) 54; RV32IF-NEXT: lui a0, %hi(G+36) 55; RV32IF-NEXT: flw ft1, %lo(G+36)(a0) 56; RV32IF-NEXT: fsw ft0, %lo(G+36)(a0) 57; RV32IF-NEXT: fmv.x.w a0, ft0 58; RV32IF-NEXT: ret 59 %1 = fadd float %a, %b 60 %2 = load volatile float, float* @G 61 store float %1, float* @G 62 %3 = getelementptr float, float* @G, i32 9 63 %4 = load volatile float, float* %3 64 store float %1, float* %3 65 ret float %1 66} 67 68; Ensure that 1 is added to the high 20 bits if bit 11 of the low part is 1 69define float @flw_fsw_constant(float %a) nounwind { 70; RV32IF-LABEL: flw_fsw_constant: 71; RV32IF: # %bb.0: 72; RV32IF-NEXT: fmv.w.x ft0, a0 73; RV32IF-NEXT: lui a0, 912092 74; RV32IF-NEXT: flw ft1, -273(a0) 75; RV32IF-NEXT: fadd.s ft0, ft0, ft1 76; RV32IF-NEXT: fsw ft0, -273(a0) 77; RV32IF-NEXT: fmv.x.w a0, ft0 78; RV32IF-NEXT: ret 79 %1 = inttoptr i32 3735928559 to float* 80 %2 = load volatile float, float* %1 81 %3 = fadd float %a, %2 82 store float %3, float* %1 83 ret float %3 84} 85 86declare void @notdead(i8*) 87 88define float @flw_stack(float %a) nounwind { 89; RV32IF-LABEL: flw_stack: 90; RV32IF: # %bb.0: 91; RV32IF-NEXT: addi sp, sp, -16 92; RV32IF-NEXT: sw ra, 12(sp) 93; RV32IF-NEXT: sw s1, 8(sp) 94; RV32IF-NEXT: mv s1, a0 95; RV32IF-NEXT: lui a0, %hi(notdead) 96; RV32IF-NEXT: addi a1, a0, %lo(notdead) 97; RV32IF-NEXT: addi a0, sp, 4 98; RV32IF-NEXT: jalr a1 99; RV32IF-NEXT: fmv.w.x ft0, s1 100; RV32IF-NEXT: flw ft1, 4(sp) 101; RV32IF-NEXT: fadd.s ft0, ft1, ft0 102; RV32IF-NEXT: fmv.x.w a0, ft0 103; RV32IF-NEXT: lw s1, 8(sp) 104; RV32IF-NEXT: lw ra, 12(sp) 105; RV32IF-NEXT: addi sp, sp, 16 106; RV32IF-NEXT: ret 107 %1 = alloca float, align 4 108 %2 = bitcast float* %1 to i8* 109 call void @notdead(i8* %2) 110 %3 = load float, float* %1 111 %4 = fadd float %3, %a ; force load in to FPR32 112 ret float %4 113} 114 115define void @fsw_stack(float %a, float %b) nounwind { 116; RV32IF-LABEL: fsw_stack: 117; RV32IF: # %bb.0: 118; RV32IF-NEXT: addi sp, sp, -16 119; RV32IF-NEXT: sw ra, 12(sp) 120; RV32IF-NEXT: fmv.w.x ft0, a1 121; RV32IF-NEXT: fmv.w.x ft1, a0 122; RV32IF-NEXT: fadd.s ft0, ft1, ft0 123; RV32IF-NEXT: fsw ft0, 8(sp) 124; RV32IF-NEXT: lui a0, %hi(notdead) 125; RV32IF-NEXT: addi a1, a0, %lo(notdead) 126; RV32IF-NEXT: addi a0, sp, 8 127; RV32IF-NEXT: jalr a1 128; RV32IF-NEXT: lw ra, 12(sp) 129; RV32IF-NEXT: addi sp, sp, 16 130; RV32IF-NEXT: ret 131 %1 = fadd float %a, %b ; force store from FPR32 132 %2 = alloca float, align 4 133 store float %1, float* %2 134 %3 = bitcast float* %2 to i8* 135 call void @notdead(i8* %3) 136 ret void 137} 138