; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=riscv32 -mattr=+zdinx,+zilsd -verify-machineinstrs \ ; RUN: -code-model=medium < %s | FileCheck %s @g_0 = global double 0.0 define double @load_g_0() nounwind { ; CHECK-LABEL: load_g_0: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: .Lpcrel_hi0: ; CHECK-NEXT: auipc a0, %pcrel_hi(g_0) ; CHECK-NEXT: ld a0, %pcrel_lo(.Lpcrel_hi0)(a0) ; CHECK-NEXT: ret entry: %0 = load double, ptr @g_0 ret double %0 } define void @store_g_0() nounwind { ; CHECK-LABEL: store_g_0: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: .Lpcrel_hi1: ; CHECK-NEXT: auipc a0, %pcrel_hi(g_0) ; CHECK-NEXT: sd zero, %pcrel_lo(.Lpcrel_hi1)(a0) ; CHECK-NEXT: ret entry: store double 0.0, ptr @g_0 ret void } %struct.S = type { double, double } define double @fold_addi_from_different_bb(i32 %k, i32 %n, ptr %a) nounwind { ; CHECK-LABEL: fold_addi_from_different_bb: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: addi sp, sp, -32 ; CHECK-NEXT: sw ra, 28(sp) # 4-byte Folded Spill ; CHECK-NEXT: sw s4, 24(sp) # 4-byte Folded Spill ; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill ; CHECK-NEXT: sd s2, 8(sp) # 8-byte Folded Spill ; CHECK-NEXT: blez a1, .LBB2_3 ; CHECK-NEXT: # %bb.1: # %for.body.lr.ph ; CHECK-NEXT: mv s2, a2 ; CHECK-NEXT: mv s3, a1 ; CHECK-NEXT: fmv.d s0, zero ; CHECK-NEXT: slli a0, a0, 4 ; CHECK-NEXT: add s4, a2, a0 ; CHECK-NEXT: .LBB2_2: # %for.body ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 ; CHECK-NEXT: mv a0, s2 ; CHECK-NEXT: call f ; CHECK-NEXT: ld a0, 8(s4) ; CHECK-NEXT: addi s3, s3, -1 ; CHECK-NEXT: fadd.d s0, a0, s0 ; CHECK-NEXT: bnez s3, .LBB2_2 ; CHECK-NEXT: j .LBB2_4 ; CHECK-NEXT: .LBB2_3: ; CHECK-NEXT: fmv.d s0, zero ; CHECK-NEXT: .LBB2_4: # %for.cond.cleanup ; CHECK-NEXT: fmv.d a0, s0 ; CHECK-NEXT: lw ra, 28(sp) # 4-byte Folded Reload ; CHECK-NEXT: lw s4, 24(sp) # 4-byte Folded Reload ; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload ; CHECK-NEXT: ld s2, 8(sp) # 8-byte Folded Reload ; CHECK-NEXT: addi sp, sp, 32 ; CHECK-NEXT: ret entry: %cmp4 = icmp sgt i32 %n, 0 br i1 %cmp4, label %for.body.lr.ph, label %for.cond.cleanup for.body.lr.ph: ; preds = %entry %y = getelementptr inbounds %struct.S, ptr %a, i32 %k, i32 1 br label %for.body for.cond.cleanup: ; preds = %for.body, %entry %s.0.lcssa = phi double [ 0.0, %entry ], [ %add, %for.body ] ret double %s.0.lcssa for.body: ; preds = %for.body.lr.ph, %for.body %i.06 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ] %s.05 = phi double [ 0.0, %for.body.lr.ph ], [ %add, %for.body ] call void @f(ptr %a) %0 = load double, ptr %y, align 8 %add = fadd double %0, %s.05 %inc = add nuw nsw i32 %i.06, 1 %exitcond.not = icmp eq i32 %inc, %n br i1 %exitcond.not, label %for.cond.cleanup, label %for.body } declare void @f(ptr) define void @split_offset(ptr %dest, double %x) { ; CHECK-LABEL: split_offset: ; CHECK: # %bb.0: ; CHECK-NEXT: mv a3, a2 ; CHECK-NEXT: addi a0, a0, 2047 ; CHECK-NEXT: mv a2, a1 ; CHECK-NEXT: sd a2, 1(a0) ; CHECK-NEXT: sd a2, 9(a0) ; CHECK-NEXT: sd a2, 17(a0) ; CHECK-NEXT: sd a2, 25(a0) ; CHECK-NEXT: ret %p1 = getelementptr double, ptr %dest, i32 256 store double %x, ptr %p1 %p2 = getelementptr double, ptr %dest, i32 257 store double %x, ptr %p2 %p3 = getelementptr double, ptr %dest, i32 258 store double %x, ptr %p3 %p4 = getelementptr double, ptr %dest, i32 259 store double %x, ptr %p4 ret void }