@@ -28,3 +28,91 @@ entry:
2828 store double 0 .0 , ptr @g_0
2929 ret void
3030}
31+
32+ %struct.S = type { double , double }
33+
34+ define double @fold_addi_from_different_bb (i32 %k , i32 %n , ptr %a ) nounwind {
35+ ; CHECK-LABEL: fold_addi_from_different_bb:
36+ ; CHECK: # %bb.0: # %entry
37+ ; CHECK-NEXT: addi sp, sp, -32
38+ ; CHECK-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
39+ ; CHECK-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
40+ ; CHECK-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
41+ ; CHECK-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
42+ ; CHECK-NEXT: sw s3, 12(sp) # 4-byte Folded Spill
43+ ; CHECK-NEXT: sw s4, 8(sp) # 4-byte Folded Spill
44+ ; CHECK-NEXT: blez a1, .LBB2_3
45+ ; CHECK-NEXT: # %bb.1: # %for.body.lr.ph
46+ ; CHECK-NEXT: mv s0, a2
47+ ; CHECK-NEXT: mv s1, a1
48+ ; CHECK-NEXT: slli a0, a0, 4
49+ ; CHECK-NEXT: add s4, a2, a0
50+ ; CHECK-NEXT: fcvt.d.w s2, zero
51+ ; CHECK-NEXT: .LBB2_2: # %for.body
52+ ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
53+ ; CHECK-NEXT: mv a0, s0
54+ ; CHECK-NEXT: call f
55+ ; CHECK-NEXT: ld a0, 8(s4)
56+ ; CHECK-NEXT: addi s1, s1, -1
57+ ; CHECK-NEXT: fadd.d s2, a0, s2
58+ ; CHECK-NEXT: bnez s1, .LBB2_2
59+ ; CHECK-NEXT: j .LBB2_4
60+ ; CHECK-NEXT: .LBB2_3:
61+ ; CHECK-NEXT: fcvt.d.w s2, zero
62+ ; CHECK-NEXT: .LBB2_4: # %for.cond.cleanup
63+ ; CHECK-NEXT: mv a0, s2
64+ ; CHECK-NEXT: mv a1, s3
65+ ; CHECK-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
66+ ; CHECK-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
67+ ; CHECK-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
68+ ; CHECK-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
69+ ; CHECK-NEXT: lw s3, 12(sp) # 4-byte Folded Reload
70+ ; CHECK-NEXT: lw s4, 8(sp) # 4-byte Folded Reload
71+ ; CHECK-NEXT: addi sp, sp, 32
72+ ; CHECK-NEXT: ret
73+ entry:
74+ %cmp4 = icmp sgt i32 %n , 0
75+ br i1 %cmp4 , label %for.body.lr.ph , label %for.cond.cleanup
76+
77+ for.body.lr.ph: ; preds = %entry
78+ %y = getelementptr inbounds %struct.S , ptr %a , i32 %k , i32 1
79+ br label %for.body
80+
81+ for.cond.cleanup: ; preds = %for.body, %entry
82+ %s.0.lcssa = phi double [ 0 .0 , %entry ], [ %add , %for.body ]
83+ ret double %s.0.lcssa
84+
85+ for.body: ; preds = %for.body.lr.ph, %for.body
86+ %i.06 = phi i32 [ 0 , %for.body.lr.ph ], [ %inc , %for.body ]
87+ %s.05 = phi double [ 0 .0 , %for.body.lr.ph ], [ %add , %for.body ]
88+ call void @f (ptr %a )
89+ %0 = load double , ptr %y , align 8
90+ %add = fadd double %0 , %s.05
91+ %inc = add nuw nsw i32 %i.06 , 1
92+ %exitcond.not = icmp eq i32 %inc , %n
93+ br i1 %exitcond.not , label %for.cond.cleanup , label %for.body
94+ }
95+
96+ declare void @f (ptr )
97+
98+ define void @split_offset (ptr %dest , double %x ) {
99+ ; CHECK-LABEL: split_offset:
100+ ; CHECK: # %bb.0:
101+ ; CHECK-NEXT: mv a3, a2
102+ ; CHECK-NEXT: addi a0, a0, 2047
103+ ; CHECK-NEXT: mv a2, a1
104+ ; CHECK-NEXT: sd a2, 1(a0)
105+ ; CHECK-NEXT: sd a2, 9(a0)
106+ ; CHECK-NEXT: sd a2, 17(a0)
107+ ; CHECK-NEXT: sd a2, 25(a0)
108+ ; CHECK-NEXT: ret
109+ %p1 = getelementptr double , ptr %dest , i32 256
110+ store double %x , ptr %p1
111+ %p2 = getelementptr double , ptr %dest , i32 257
112+ store double %x , ptr %p2
113+ %p3 = getelementptr double , ptr %dest , i32 258
114+ store double %x , ptr %p3
115+ %p4 = getelementptr double , ptr %dest , i32 259
116+ store double %x , ptr %p4
117+ ret void
118+ }
0 commit comments