1+ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+ ; RUN: opt -S -passes='inline,instcombine' < %s | FileCheck %s
3+
4+ define float @inline_rec_true_successor (float %x , float %scale ) {
5+ ; CHECK-LABEL: define float @inline_rec_true_successor(
6+ ; CHECK-SAME: float [[X:%.*]], float [[SCALE:%.*]]) {
7+ ; CHECK-NEXT: [[ENTRY:.*:]]
8+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[X]], 0.000000e+00
9+ ; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
10+ ; CHECK: [[COMMON_RET18:.*]]:
11+ ; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_TRUE_SUCCESSOR_EXIT:.*]] ], [ [[MUL:%.*]], %[[IF_END]] ]
12+ ; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
13+ ; CHECK: [[IF_THEN]]:
14+ ; CHECK-NEXT: br i1 false, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]
15+ ; CHECK: [[IF_THEN_I]]:
16+ ; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]
17+ ; CHECK: [[IF_END_I]]:
18+ ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[X]]
19+ ; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]
20+ ; CHECK-NEXT: br label %[[INLINE_REC_TRUE_SUCCESSOR_EXIT]]
21+ ; CHECK: [[INLINE_REC_TRUE_SUCCESSOR_EXIT]]:
22+ ; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ poison, %[[IF_THEN_I]] ], [ [[MUL_I]], %[[IF_END_I]] ]
23+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
24+ ; CHECK: [[IF_END]]:
25+ ; CHECK-NEXT: [[MUL]] = fmul float [[X]], [[SCALE]]
26+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
27+ ;
28+ entry:
29+ %cmp = fcmp olt float %x , 0 .000000e+00
30+ br i1 %cmp , label %if.then , label %if.end
31+
32+ common .ret18: ; preds = %if.then, %if.end
33+ %common.ret18.op = phi float [ %call , %if.then ], [ %mul , %if.end ]
34+ ret float %common.ret18.op
35+
36+ if.then: ; preds = %entry
37+ %fneg = fneg float %x
38+ %call = tail call float @inline_rec_true_successor (float %fneg , float %scale )
39+ br label %common.ret18
40+
41+ if.end: ; preds = %entry
42+ %mul = fmul float %x , %scale
43+ br label %common.ret18
44+ }
45+
46+ define float @test_inline_rec_true_successor (float %x , float %scale ) {
47+ entry:
48+ %res = tail call float @inline_rec_true_successor (float %x , float %scale )
49+ ret float %res
50+ }
51+
52+ ; Same as previous test except that the recursive callsite is in the false successor
53+ define float @inline_rec_false_successor (float %x , float %scale ) {
54+ ; CHECK-LABEL: define float @inline_rec_false_successor(
55+ ; CHECK-SAME: float [[Y:%.*]], float [[SCALE:%.*]]) {
56+ ; CHECK-NEXT: [[ENTRY:.*:]]
57+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp uge float [[Y]], 0.000000e+00
58+ ; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
59+ ; CHECK: [[COMMON_RET18:.*]]:
60+ ; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[MUL:%.*]], %[[IF_THEN]] ], [ [[COMMON_RET18_OP_I:%.*]], %[[INLINE_REC_FALSE_SUCCESSOR_EXIT:.*]] ]
61+ ; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
62+ ; CHECK: [[IF_THEN]]:
63+ ; CHECK-NEXT: [[MUL]] = fmul float [[Y]], [[SCALE]]
64+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
65+ ; CHECK: [[IF_END]]:
66+ ; CHECK-NEXT: br i1 true, label %[[IF_THEN_I:.*]], label %[[IF_END_I:.*]]
67+ ; CHECK: [[IF_THEN_I]]:
68+ ; CHECK-NEXT: [[FNEG:%.*]] = fneg float [[Y]]
69+ ; CHECK-NEXT: [[MUL_I:%.*]] = fmul float [[SCALE]], [[FNEG]]
70+ ; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]
71+ ; CHECK: [[IF_END_I]]:
72+ ; CHECK-NEXT: br label %[[INLINE_REC_FALSE_SUCCESSOR_EXIT]]
73+ ; CHECK: [[INLINE_REC_FALSE_SUCCESSOR_EXIT]]:
74+ ; CHECK-NEXT: [[COMMON_RET18_OP_I]] = phi float [ [[MUL_I]], %[[IF_THEN_I]] ], [ poison, %[[IF_END_I]] ]
75+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
76+ ;
77+ entry:
78+ %cmp = fcmp uge float %x , 0 .000000e+00
79+ br i1 %cmp , label %if.then , label %if.end
80+
81+ common .ret18: ; preds = %if.then, %if.end
82+ %common.ret18.op = phi float [ %mul , %if.then ], [ %call , %if.end ]
83+ ret float %common.ret18.op
84+
85+ if.then: ; preds = %entry
86+ %mul = fmul float %x , %scale
87+ br label %common.ret18
88+
89+ if.end: ; preds = %entry
90+ %fneg = fneg float %x
91+ %call = tail call float @inline_rec_false_successor (float %fneg , float %scale )
92+ br label %common.ret18
93+ }
94+
95+ define float @test_inline_rec_false_successor (float %x , float %scale ) {
96+ entry:
97+ %res = tail call float @inline_rec_false_successor (float %x , float %scale )
98+ ret float %res
99+ }
100+
101+ ; Test when the BR has Value not cmp instruction
102+ define float @inline_rec_no_cmp (i1 %flag , float %scale ) {
103+ ; CHECK-LABEL: define float @inline_rec_no_cmp(
104+ ; CHECK-SAME: i1 [[FLAG:%.*]], float [[SCALE:%.*]]) {
105+ ; CHECK-NEXT: [[ENTRY:.*:]]
106+ ; CHECK-NEXT: br i1 [[FLAG]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
107+ ; CHECK: [[IF_THEN]]:
108+ ; CHECK-NEXT: [[SUM:%.*]] = fadd float [[SCALE]], 5.000000e+00
109+ ; CHECK-NEXT: [[SUM1:%.*]] = fadd float [[SUM]], [[SCALE]]
110+ ; CHECK-NEXT: br label %[[COMMON_RET:.*]]
111+ ; CHECK: [[IF_END]]:
112+ ; CHECK-NEXT: [[SUM2:%.*]] = fadd float [[SCALE]], 5.000000e+00
113+ ; CHECK-NEXT: br label %[[COMMON_RET]]
114+ ; CHECK: [[COMMON_RET]]:
115+ ; CHECK-NEXT: [[COMMON_RET_RES:%.*]] = phi float [ [[SUM1]], %[[IF_THEN]] ], [ [[SUM2]], %[[IF_END]] ]
116+ ; CHECK-NEXT: ret float [[COMMON_RET_RES]]
117+ ;
118+ entry:
119+ br i1 %flag , label %if.then , label %if.end
120+ if.then:
121+ %res = tail call float @inline_rec_no_cmp (i1 false , float %scale )
122+ %sum1 = fadd float %res , %scale
123+ br label %common.ret
124+ if.end:
125+ %sum2 = fadd float %scale , 5 .000000e+00
126+ br label %common.ret
127+ common .ret:
128+ %common.ret.res = phi float [ %sum1 , %if.then ], [ %sum2 , %if.end ]
129+ ret float %common.ret.res
130+ }
131+
132+ define float @test_inline_rec_no_cmp (i1 %flag , float %scale ) {
133+ entry:
134+ %res = tail call float @inline_rec_no_cmp (i1 %flag , float %scale )
135+ ret float %res
136+ }
137+
138+ define float @no_inline_rec (float %x , float %scale ) {
139+ ; CHECK-LABEL: define float @no_inline_rec(
140+ ; CHECK-SAME: float [[Z:%.*]], float [[SCALE:%.*]]) {
141+ ; CHECK-NEXT: [[ENTRY:.*:]]
142+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp olt float [[Z]], 5.000000e+00
143+ ; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
144+ ; CHECK: [[COMMON_RET18:.*]]:
145+ ; CHECK-NEXT: [[COMMON_RET18_OP:%.*]] = phi float [ [[FNEG1:%.*]], %[[IF_THEN]] ], [ [[MUL:%.*]], %[[IF_END]] ]
146+ ; CHECK-NEXT: ret float [[COMMON_RET18_OP]]
147+ ; CHECK: [[IF_THEN]]:
148+ ; CHECK-NEXT: [[FADD:%.*]] = fadd float [[Z]], 5.000000e+00
149+ ; CHECK-NEXT: [[CALL:%.*]] = tail call float @no_inline_rec(float [[FADD]], float [[SCALE]])
150+ ; CHECK-NEXT: [[FNEG1]] = fneg float [[CALL]]
151+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
152+ ; CHECK: [[IF_END]]:
153+ ; CHECK-NEXT: [[MUL]] = fmul float [[Z]], [[SCALE]]
154+ ; CHECK-NEXT: br label %[[COMMON_RET18]]
155+ ;
156+ entry:
157+ %cmp = fcmp olt float %x , 5 .000000e+00
158+ br i1 %cmp , label %if.then , label %if.end
159+
160+ common .ret18: ; preds = %if.then, %if.end
161+ %common.ret18.op = phi float [ %fneg1 , %if.then ], [ %mul , %if.end ]
162+ ret float %common.ret18.op
163+
164+ if.then: ; preds = %entry
165+ %fadd = fadd float %x , 5 .000000e+00
166+ %call = tail call float @no_inline_rec (float %fadd , float %scale )
167+ %fneg1 = fneg float %call
168+ br label %common.ret18
169+
170+ if.end: ; preds = %entry
171+ %mul = fmul float %x , %scale
172+ br label %common.ret18
173+ }
174+
175+ define float @test_no_inline (float %x , float %scale ) {
176+ entry:
177+ %res = tail call float @no_inline_rec (float %x , float %scale )
178+ ret float %res
179+ }
0 commit comments