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