| ; 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 s0, 24(sp) # 4-byte Folded Spill |
| ; CHECK-NEXT: sw s1, 20(sp) # 4-byte Folded Spill |
| ; CHECK-NEXT: sw s2, 16(sp) # 4-byte Folded Spill |
| ; CHECK-NEXT: sw s3, 12(sp) # 4-byte Folded Spill |
| ; CHECK-NEXT: sw s4, 8(sp) # 4-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: li s0, 0 |
| ; CHECK-NEXT: li s1, 0 |
| ; 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: li s0, 0 |
| ; CHECK-NEXT: li s1, 0 |
| ; CHECK-NEXT: .LBB2_4: # %for.cond.cleanup |
| ; CHECK-NEXT: mv a0, s0 |
| ; CHECK-NEXT: mv a1, s1 |
| ; CHECK-NEXT: lw ra, 28(sp) # 4-byte Folded Reload |
| ; CHECK-NEXT: lw s0, 24(sp) # 4-byte Folded Reload |
| ; CHECK-NEXT: lw s1, 20(sp) # 4-byte Folded Reload |
| ; CHECK-NEXT: lw s2, 16(sp) # 4-byte Folded Reload |
| ; CHECK-NEXT: lw s3, 12(sp) # 4-byte Folded Reload |
| ; CHECK-NEXT: lw s4, 8(sp) # 4-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 |
| } |