@@ -28,3 +28,91 @@ entry:
28
28
store double 0 .0 , ptr @g_0
29
29
ret void
30
30
}
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