Skip to content

Commit

Permalink
[loongarch][DAG][FREEZE] Fix crash when FREEZE a half(f16) type on lo…
Browse files Browse the repository at this point in the history
…ongarch (#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`:
- #93894
- #94456

Also see: other float promotion FREEZE handling
-
0019c2f
  • Loading branch information
yxd-ym authored Sep 13, 2024
1 parent 981bb9d commit 13280d9
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 72 deletions.
2 changes: 2 additions & 0 deletions llvm/lib/Target/LoongArch/LoongArchISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ class LoongArchTargetLowering : public TargetLowering {
bool isEligibleForTailCallOptimization(
CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
const SmallVectorImpl<CCValAssign> &ArgLocs) const;

bool softPromoteHalfType() const override { return true; }
};

} // end namespace llvm
Expand Down
198 changes: 126 additions & 72 deletions llvm/test/CodeGen/LoongArch/fp16-promote.ll
Original file line number Diff line number Diff line change
Expand Up @@ -126,42 +126,40 @@ define void @test_fptrunc_double(double %d, ptr %p) nounwind {
define half @test_fadd_reg(half %a, half %b) nounwind {
; LA32-LABEL: test_fadd_reg:
; LA32: # %bb.0:
; LA32-NEXT: addi.w $sp, $sp, -32
; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
; LA32-NEXT: addi.w $sp, $sp, -16
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
; LA32-NEXT: move $fp, $a0
; LA32-NEXT: move $a0, $a1
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs0, $fa0
; LA32-NEXT: fmov.s $fa0, $fa1
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: move $a0, $fp
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs1, $fa0
; LA32-NEXT: fmov.s $fa0, $fs0
; LA32-NEXT: fadd.s $fa0, $fa0, $fs0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fadd.s $fa0, $fa0, $fs1
; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 32
; LA32-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
;
; LA64-LABEL: test_fadd_reg:
; LA64: # %bb.0:
; LA64-NEXT: addi.d $sp, $sp, -32
; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: move $fp, $a0
; LA64-NEXT: move $a0, $a1
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs0, $fa0
; LA64-NEXT: fmov.s $fa0, $fa1
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: move $a0, $fp
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs1, $fa0
; LA64-NEXT: fmov.s $fa0, $fs0
; LA64-NEXT: fadd.s $fa0, $fa0, $fs0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fadd.s $fa0, $fa0, $fs1
; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload
; LA64-NEXT: addi.d $sp, $sp, 32
; LA64-NEXT: ret
Expand All @@ -177,16 +175,16 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill
; LA32-NEXT: st.w $s0, $sp, 20 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
; LA32-NEXT: move $fp, $a1
; LA32-NEXT: move $s0, $a0
; LA32-NEXT: ld.hu $a0, $a0, 0
; LA32-NEXT: move $fp, $a0
; LA32-NEXT: ld.hu $s0, $a0, 0
; LA32-NEXT: ld.hu $a0, $a1, 0
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs0, $fa0
; LA32-NEXT: ld.hu $a0, $fp, 0
; LA32-NEXT: move $a0, $s0
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fadd.s $fa0, $fs0, $fa0
; LA32-NEXT: fadd.s $fa0, $fa0, $fs0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: st.h $a0, $s0, 0
; LA32-NEXT: st.h $a0, $fp, 0
; LA32-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
; LA32-NEXT: ld.w $s0, $sp, 20 # 4-byte Folded Reload
; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload
Expand All @@ -201,16 +199,16 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
; LA64-NEXT: move $fp, $a1
; LA64-NEXT: move $s0, $a0
; LA64-NEXT: ld.hu $a0, $a0, 0
; LA64-NEXT: move $fp, $a0
; LA64-NEXT: ld.hu $s0, $a0, 0
; LA64-NEXT: ld.hu $a0, $a1, 0
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs0, $fa0
; LA64-NEXT: ld.hu $a0, $fp, 0
; LA64-NEXT: move $a0, $s0
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fadd.s $fa0, $fs0, $fa0
; LA64-NEXT: fadd.s $fa0, $fa0, $fs0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: st.h $a0, $s0, 0
; LA64-NEXT: st.h $a0, $fp, 0
; LA64-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
Expand All @@ -227,42 +225,40 @@ define void @test_fadd_mem(ptr %p, ptr %q) nounwind {
define half @test_fmul_reg(half %a, half %b) nounwind {
; LA32-LABEL: test_fmul_reg:
; LA32: # %bb.0:
; LA32-NEXT: addi.w $sp, $sp, -32
; LA32-NEXT: st.w $ra, $sp, 28 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
; LA32-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
; LA32-NEXT: addi.w $sp, $sp, -16
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-NEXT: st.w $fp, $sp, 8 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
; LA32-NEXT: move $fp, $a0
; LA32-NEXT: move $a0, $a1
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs0, $fa0
; LA32-NEXT: fmov.s $fa0, $fa1
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: move $a0, $fp
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs1, $fa0
; LA32-NEXT: fmov.s $fa0, $fs0
; LA32-NEXT: fmul.s $fa0, $fa0, $fs0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmul.s $fa0, $fa0, $fs1
; LA32-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
; LA32-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
; LA32-NEXT: ld.w $ra, $sp, 28 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 32
; LA32-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
; LA32-NEXT: ld.w $fp, $sp, 8 # 4-byte Folded Reload
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
;
; LA64-LABEL: test_fmul_reg:
; LA64: # %bb.0:
; LA64-NEXT: addi.d $sp, $sp, -32
; LA64-NEXT: st.d $ra, $sp, 24 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs1, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: move $fp, $a0
; LA64-NEXT: move $a0, $a1
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs0, $fa0
; LA64-NEXT: fmov.s $fa0, $fa1
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: move $a0, $fp
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs1, $fa0
; LA64-NEXT: fmov.s $fa0, $fs0
; LA64-NEXT: fmul.s $fa0, $fa0, $fs0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmul.s $fa0, $fa0, $fs1
; LA64-NEXT: fld.d $fs1, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: fld.d $fs0, $sp, 16 # 8-byte Folded Reload
; LA64-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
; LA64-NEXT: ld.d $ra, $sp, 24 # 8-byte Folded Reload
; LA64-NEXT: addi.d $sp, $sp, 32
; LA64-NEXT: ret
Expand All @@ -278,16 +274,16 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
; LA32-NEXT: st.w $fp, $sp, 24 # 4-byte Folded Spill
; LA32-NEXT: st.w $s0, $sp, 20 # 4-byte Folded Spill
; LA32-NEXT: fst.d $fs0, $sp, 8 # 8-byte Folded Spill
; LA32-NEXT: move $fp, $a1
; LA32-NEXT: move $s0, $a0
; LA32-NEXT: ld.hu $a0, $a0, 0
; LA32-NEXT: move $fp, $a0
; LA32-NEXT: ld.hu $s0, $a0, 0
; LA32-NEXT: ld.hu $a0, $a1, 0
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmov.s $fs0, $fa0
; LA32-NEXT: ld.hu $a0, $fp, 0
; LA32-NEXT: move $a0, $s0
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fmul.s $fa0, $fs0, $fa0
; LA32-NEXT: fmul.s $fa0, $fa0, $fs0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: st.h $a0, $s0, 0
; LA32-NEXT: st.h $a0, $fp, 0
; LA32-NEXT: fld.d $fs0, $sp, 8 # 8-byte Folded Reload
; LA32-NEXT: ld.w $s0, $sp, 20 # 4-byte Folded Reload
; LA32-NEXT: ld.w $fp, $sp, 24 # 4-byte Folded Reload
Expand All @@ -302,16 +298,16 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
; LA64-NEXT: st.d $fp, $sp, 16 # 8-byte Folded Spill
; LA64-NEXT: st.d $s0, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: fst.d $fs0, $sp, 0 # 8-byte Folded Spill
; LA64-NEXT: move $fp, $a1
; LA64-NEXT: move $s0, $a0
; LA64-NEXT: ld.hu $a0, $a0, 0
; LA64-NEXT: move $fp, $a0
; LA64-NEXT: ld.hu $s0, $a0, 0
; LA64-NEXT: ld.hu $a0, $a1, 0
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmov.s $fs0, $fa0
; LA64-NEXT: ld.hu $a0, $fp, 0
; LA64-NEXT: move $a0, $s0
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fmul.s $fa0, $fs0, $fa0
; LA64-NEXT: fmul.s $fa0, $fa0, $fs0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: st.h $a0, $s0, 0
; LA64-NEXT: st.h $a0, $fp, 0
; LA64-NEXT: fld.d $fs0, $sp, 0 # 8-byte Folded Reload
; LA64-NEXT: ld.d $s0, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: ld.d $fp, $sp, 16 # 8-byte Folded Reload
Expand All @@ -324,3 +320,61 @@ define void @test_fmul_mem(ptr %p, ptr %q) nounwind {
store half %r, ptr %p
ret void
}

define half @freeze_half_undef() nounwind {
; LA32-LABEL: freeze_half_undef:
; LA32: # %bb.0:
; LA32-NEXT: addi.w $sp, $sp, -16
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-NEXT: movgr2fr.w $fa0, $zero
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fadd.s $fa0, $fa0, $fa0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
;
; LA64-LABEL: freeze_half_undef:
; LA64: # %bb.0:
; LA64-NEXT: addi.d $sp, $sp, -16
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: movgr2fr.w $fa0, $zero
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fadd.s $fa0, $fa0, $fa0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: addi.d $sp, $sp, 16
; LA64-NEXT: ret
%y1 = freeze half undef
%t1 = fadd half %y1, %y1
ret half %t1
}

define half @freeze_half_poison(half %maybe.poison) nounwind {
; LA32-LABEL: freeze_half_poison:
; LA32: # %bb.0:
; LA32-NEXT: addi.w $sp, $sp, -16
; LA32-NEXT: st.w $ra, $sp, 12 # 4-byte Folded Spill
; LA32-NEXT: bl %plt(__gnu_h2f_ieee)
; LA32-NEXT: fadd.s $fa0, $fa0, $fa0
; LA32-NEXT: bl %plt(__gnu_f2h_ieee)
; LA32-NEXT: ld.w $ra, $sp, 12 # 4-byte Folded Reload
; LA32-NEXT: addi.w $sp, $sp, 16
; LA32-NEXT: ret
;
; LA64-LABEL: freeze_half_poison:
; LA64: # %bb.0:
; LA64-NEXT: addi.d $sp, $sp, -16
; LA64-NEXT: st.d $ra, $sp, 8 # 8-byte Folded Spill
; LA64-NEXT: bl %plt(__gnu_h2f_ieee)
; LA64-NEXT: fadd.s $fa0, $fa0, $fa0
; LA64-NEXT: bl %plt(__gnu_f2h_ieee)
; LA64-NEXT: ld.d $ra, $sp, 8 # 8-byte Folded Reload
; LA64-NEXT: addi.d $sp, $sp, 16
; LA64-NEXT: ret
%y1 = freeze half %maybe.poison
%t1 = fadd half %y1, %y1
ret half %t1
}

0 comments on commit 13280d9

Please sign in to comment.