Skip to content

Commit bd494f3

Browse files
yxd-ymheiher
authored andcommitted
[loongarch][DAG][FREEZE] Fix crash when FREEZE a half(f16) type on loongarch (llvm#107791)
For zig with LLVM 19.1.0rc4, we are seeing the following error when bootstrapping a `loongarch64-linux-musl` target. ziglang/zig-bootstrap#164 (comment) It seems that this issue is caused by `PromoteFloatResult` is not handling FREEZE OP on loongarch. Here is the reproduction of the error: https://godbolt.org/z/PPfvWjjG5 ~~This patch adds the FREEZE OP handling with `PromoteFloatRes_UnaryOp` and adds a test case.~~ This patch changes loongarch's way of floating point promotion to soft promotion to avoid this problem. See: loongarch's handling of `half`: - llvm#93894 - llvm#94456 Also see: other float promotion FREEZE handling - llvm@0019c2f (cherry picked from commit 13280d9)
1 parent 7ba7d8e commit bd494f3

File tree

2 files changed

+128
-72
lines changed

2 files changed

+128
-72
lines changed

Diff for: llvm/lib/Target/LoongArch/LoongArchISelLowering.h

+2
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ class LoongArchTargetLowering : public TargetLowering {
332332
bool isEligibleForTailCallOptimization(
333333
CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
334334
const SmallVectorImpl<CCValAssign> &ArgLocs) const;
335+
336+
bool softPromoteHalfType() const override { return true; }
335337
};
336338

337339
} // end namespace llvm

Diff for: llvm/test/CodeGen/LoongArch/fp16-promote.ll

+126-72
Original file line numberDiff line numberDiff line change
@@ -126,42 +126,40 @@ define void @test_fptrunc_double(double %d, ptr %p) nounwind {
126126
define half @test_fadd_reg(half %a, half %b) nounwind {
127127
; LA32-LABEL: test_fadd_reg:
128128
; LA32: # %bb.0:
129-
; LA32-NEXT: addi.w $sp, $sp, -32
130-
; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill
131-
; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
132-
; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
129+
; LA32-NEXT: addi.w $sp, $sp, -16
130+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
131+
; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
132+
; LA32-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
133+
; LA32-NEXT: move $fp, $a0
134+
; LA32-NEXT: move $a0, $a1
135+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
133136
; LA32-NEXT: fmov.s $fs0, $fa0
134-
; LA32-NEXT: fmov.s $fa0, $fa1
135-
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
137+
; LA32-NEXT: move $a0, $fp
136138
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
137-
; LA32-NEXT: fmov.s $fs1, $fa0
138-
; LA32-NEXT: fmov.s $fa0, $fs0
139+
; LA32-NEXT: fadd.s $fa0, $fa0, $fs0
139140
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
140-
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
141-
; LA32-NEXT: fadd.s $fa0, $fa0, $fs1
142-
; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
143-
; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
144-
; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload
145-
; LA32-NEXT: addi.w $sp, $sp, 32
141+
; LA32-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
142+
; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload
143+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
144+
; LA32-NEXT: addi.w $sp, $sp, 16
146145
; LA32-NEXT: ret
147146
;
148147
; LA64-LABEL: test_fadd_reg:
149148
; LA64: # %bb.0:
150149
; LA64-NEXT: addi.d $sp, $sp, -32
151150
; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill
152-
; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
153-
; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
151+
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
152+
; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
153+
; LA64-NEXT: move $fp, $a0
154+
; LA64-NEXT: move $a0, $a1
155+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
154156
; LA64-NEXT: fmov.s $fs0, $fa0
155-
; LA64-NEXT: fmov.s $fa0, $fa1
156-
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
157+
; LA64-NEXT: move $a0, $fp
157158
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
158-
; LA64-NEXT: fmov.s $fs1, $fa0
159-
; LA64-NEXT: fmov.s $fa0, $fs0
159+
; LA64-NEXT: fadd.s $fa0, $fa0, $fs0
160160
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
161-
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
162-
; LA64-NEXT: fadd.s $fa0, $fa0, $fs1
163-
; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
164-
; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
161+
; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
162+
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
165163
; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload
166164
; LA64-NEXT: addi.d $sp, $sp, 32
167165
; LA64-NEXT: ret
@@ -177,16 +175,16 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
177175
; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill
178176
; LA32-NEXT: st.w $s0, $sp, 20 # 4-byte Folded Spill
179177
; LA32-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
180-
; LA32-NEXT: move $fp, $a1
181-
; LA32-NEXT: move $s0, $a0
182-
; LA32-NEXT: ld.hu $a0, $a0, 0
178+
; LA32-NEXT: move $fp, $a0
179+
; LA32-NEXT: ld.hu $s0, $a0, 0
180+
; LA32-NEXT: ld.hu $a0, $a1, 0
183181
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
184182
; LA32-NEXT: fmov.s $fs0, $fa0
185-
; LA32-NEXT: ld.hu $a0, $fp, 0
183+
; LA32-NEXT: move $a0, $s0
186184
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
187-
; LA32-NEXT: fadd.s $fa0, $fs0, $fa0
185+
; LA32-NEXT: fadd.s $fa0, $fa0, $fs0
188186
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
189-
; LA32-NEXT: st.h $a0, $s0, 0
187+
; LA32-NEXT: st.h $a0, $fp, 0
190188
; LA32-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
191189
; LA32-NEXT: ld.w $s0, $sp, 20 # 4-byte Folded Reload
192190
; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload
@@ -201,16 +199,16 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
201199
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
202200
; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill
203201
; LA64-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
204-
; LA64-NEXT: move $fp, $a1
205-
; LA64-NEXT: move $s0, $a0
206-
; LA64-NEXT: ld.hu $a0, $a0, 0
202+
; LA64-NEXT: move $fp, $a0
203+
; LA64-NEXT: ld.hu $s0, $a0, 0
204+
; LA64-NEXT: ld.hu $a0, $a1, 0
207205
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
208206
; LA64-NEXT: fmov.s $fs0, $fa0
209-
; LA64-NEXT: ld.hu $a0, $fp, 0
207+
; LA64-NEXT: move $a0, $s0
210208
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
211-
; LA64-NEXT: fadd.s $fa0, $fs0, $fa0
209+
; LA64-NEXT: fadd.s $fa0, $fa0, $fs0
212210
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
213-
; LA64-NEXT: st.h $a0, $s0, 0
211+
; LA64-NEXT: st.h $a0, $fp, 0
214212
; LA64-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
215213
; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload
216214
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
@@ -227,42 +225,40 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
227225
define half @test_fmul_reg(half %a, half %b) nounwind {
228226
; LA32-LABEL: test_fmul_reg:
229227
; LA32: # %bb.0:
230-
; LA32-NEXT: addi.w $sp, $sp, -32
231-
; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill
232-
; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
233-
; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
228+
; LA32-NEXT: addi.w $sp, $sp, -16
229+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
230+
; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
231+
; LA32-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
232+
; LA32-NEXT: move $fp, $a0
233+
; LA32-NEXT: move $a0, $a1
234+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
234235
; LA32-NEXT: fmov.s $fs0, $fa0
235-
; LA32-NEXT: fmov.s $fa0, $fa1
236-
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
236+
; LA32-NEXT: move $a0, $fp
237237
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
238-
; LA32-NEXT: fmov.s $fs1, $fa0
239-
; LA32-NEXT: fmov.s $fa0, $fs0
238+
; LA32-NEXT: fmul.s $fa0, $fa0, $fs0
240239
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
241-
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
242-
; LA32-NEXT: fmul.s $fa0, $fa0, $fs1
243-
; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
244-
; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
245-
; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload
246-
; LA32-NEXT: addi.w $sp, $sp, 32
240+
; LA32-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
241+
; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload
242+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
243+
; LA32-NEXT: addi.w $sp, $sp, 16
247244
; LA32-NEXT: ret
248245
;
249246
; LA64-LABEL: test_fmul_reg:
250247
; LA64: # %bb.0:
251248
; LA64-NEXT: addi.d $sp, $sp, -32
252249
; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill
253-
; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
254-
; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
250+
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
251+
; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
252+
; LA64-NEXT: move $fp, $a0
253+
; LA64-NEXT: move $a0, $a1
254+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
255255
; LA64-NEXT: fmov.s $fs0, $fa0
256-
; LA64-NEXT: fmov.s $fa0, $fa1
257-
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
256+
; LA64-NEXT: move $a0, $fp
258257
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
259-
; LA64-NEXT: fmov.s $fs1, $fa0
260-
; LA64-NEXT: fmov.s $fa0, $fs0
258+
; LA64-NEXT: fmul.s $fa0, $fa0, $fs0
261259
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
262-
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
263-
; LA64-NEXT: fmul.s $fa0, $fa0, $fs1
264-
; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
265-
; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
260+
; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
261+
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
266262
; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload
267263
; LA64-NEXT: addi.d $sp, $sp, 32
268264
; LA64-NEXT: ret
@@ -278,16 +274,16 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
278274
; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill
279275
; LA32-NEXT: st.w $s0, $sp, 20 # 4-byte Folded Spill
280276
; LA32-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
281-
; LA32-NEXT: move $fp, $a1
282-
; LA32-NEXT: move $s0, $a0
283-
; LA32-NEXT: ld.hu $a0, $a0, 0
277+
; LA32-NEXT: move $fp, $a0
278+
; LA32-NEXT: ld.hu $s0, $a0, 0
279+
; LA32-NEXT: ld.hu $a0, $a1, 0
284280
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
285281
; LA32-NEXT: fmov.s $fs0, $fa0
286-
; LA32-NEXT: ld.hu $a0, $fp, 0
282+
; LA32-NEXT: move $a0, $s0
287283
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
288-
; LA32-NEXT: fmul.s $fa0, $fs0, $fa0
284+
; LA32-NEXT: fmul.s $fa0, $fa0, $fs0
289285
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
290-
; LA32-NEXT: st.h $a0, $s0, 0
286+
; LA32-NEXT: st.h $a0, $fp, 0
291287
; LA32-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
292288
; LA32-NEXT: ld.w $s0, $sp, 20 # 4-byte Folded Reload
293289
; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload
@@ -302,16 +298,16 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
302298
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
303299
; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill
304300
; LA64-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
305-
; LA64-NEXT: move $fp, $a1
306-
; LA64-NEXT: move $s0, $a0
307-
; LA64-NEXT: ld.hu $a0, $a0, 0
301+
; LA64-NEXT: move $fp, $a0
302+
; LA64-NEXT: ld.hu $s0, $a0, 0
303+
; LA64-NEXT: ld.hu $a0, $a1, 0
308304
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
309305
; LA64-NEXT: fmov.s $fs0, $fa0
310-
; LA64-NEXT: ld.hu $a0, $fp, 0
306+
; LA64-NEXT: move $a0, $s0
311307
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
312-
; LA64-NEXT: fmul.s $fa0, $fs0, $fa0
308+
; LA64-NEXT: fmul.s $fa0, $fa0, $fs0
313309
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
314-
; LA64-NEXT: st.h $a0, $s0, 0
310+
; LA64-NEXT: st.h $a0, $fp, 0
315311
; LA64-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
316312
; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload
317313
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
@@ -324,3 +320,61 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
324320
store half %r, ptr %p
325321
ret void
326322
}
323+
324+
define half @freeze_half_undef() nounwind {
325+
; LA32-LABEL: freeze_half_undef:
326+
; LA32: # %bb.0:
327+
; LA32-NEXT: addi.w $sp, $sp, -16
328+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
329+
; LA32-NEXT: movgr2fr.w $fa0, $zero
330+
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
331+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
332+
; LA32-NEXT: fadd.s $fa0, $fa0, $fa0
333+
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
334+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
335+
; LA32-NEXT: addi.w $sp, $sp, 16
336+
; LA32-NEXT: ret
337+
;
338+
; LA64-LABEL: freeze_half_undef:
339+
; LA64: # %bb.0:
340+
; LA64-NEXT: addi.d $sp, $sp, -16
341+
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
342+
; LA64-NEXT: movgr2fr.w $fa0, $zero
343+
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
344+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
345+
; LA64-NEXT: fadd.s $fa0, $fa0, $fa0
346+
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
347+
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
348+
; LA64-NEXT: addi.d $sp, $sp, 16
349+
; LA64-NEXT: ret
350+
%y1 = freeze half undef
351+
%t1 = fadd half %y1, %y1
352+
ret half %t1
353+
}
354+
355+
define half @freeze_half_poison(half %maybe.poison) nounwind {
356+
; LA32-LABEL: freeze_half_poison:
357+
; LA32: # %bb.0:
358+
; LA32-NEXT: addi.w $sp, $sp, -16
359+
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
360+
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
361+
; LA32-NEXT: fadd.s $fa0, $fa0, $fa0
362+
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
363+
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
364+
; LA32-NEXT: addi.w $sp, $sp, 16
365+
; LA32-NEXT: ret
366+
;
367+
; LA64-LABEL: freeze_half_poison:
368+
; LA64: # %bb.0:
369+
; LA64-NEXT: addi.d $sp, $sp, -16
370+
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
371+
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
372+
; LA64-NEXT: fadd.s $fa0, $fa0, $fa0
373+
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
374+
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
375+
; LA64-NEXT: addi.d $sp, $sp, 16
376+
; LA64-NEXT: ret
377+
%y1 = freeze half %maybe.poison
378+
%t1 = fadd half %y1, %y1
379+
ret half %t1
380+
}

0 commit comments

Comments
 (0)