binary16 float-point arithmetic crashes LLVM on s390x
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Ubuntu on IBM z Systems |
New
|
Medium
|
bugproxy | ||
llvm-toolchain-18 (Ubuntu) |
New
|
Medium
|
Unassigned |
Bug Description
binary16 float-point arithmetic crashes LLVM on s390x due to the LLVM backend being unable to lower the LLVM IR to the machine code.
You can find a short reproducer below:
define noundef zeroext i1 @test_func(half noundef %f) unnamed_addr {
start:
%self = fdiv half %f, 0xHC700
%_4 = bitcast half %self to i16
%_0 = icmp slt i16 %_4, 0
ret i1 %_0
}
You can save this LLVM IR text to a file called `test-ir.ll` and build it using `clang test-ir.ll -c -o test-ir.o` on a s390x device and watch LLVM explodes with:
warning: overriding the module target triple with s390x-unknown-
fatal error: error in backend: Cannot select: 0x6005f020ae20: i32 = fp_to_fp16 0x6005f020adb0
0x6005f020adb0: f32 = fdiv 0x6005f020af70, 0x6005f020b4b0
0x6005f020af70: f32 = fp16_to_fp 0x6005f020b520
0x6005f02
0x6005f020b4b0: f32,ch = load<(load (s32) from constant-pool)> 0x6005f01e5220, 0x6005f020b280, undef:i64
0x6005f02
0x6005f02
In function: test_func
tags: | added: reverse-proxy-bugzilla s390x |
Changed in ubuntu-z-systems: | |
assignee: | nobody → bugproxy (bugproxy) |
Changed in llvm-toolchain-18 (Ubuntu): | |
importance: | Undecided → Medium |
Changed in ubuntu-z-systems: | |
importance: | Undecided → Medium |
tags: | added: architecture-s39064 bugnameltc-208024 severity-high targetmilestone-inin--- |
After some digging, I think the s390x is missing a fallback ISel path for the f16 type. Here's my preliminary fix based on PPC64 logic (may not be entirely correct):
diff --git a/llvm/ lib/Target/ SystemZ/ SystemZISelLowe ring.cpp b/llvm/ lib/Target/ SystemZ/ SystemZISelLowe ring.cpp .a2351b205bdb 100644 lib/Target/ SystemZ/ SystemZISelLowe ring.cpp lib/Target/ SystemZ/ SystemZISelLowe ring.cpp wering: :SystemZTargetL owering( const TargetMachine &TM,
setOperationAct ion(ISD: :FSINCOS, VT, Expand);
setOperationAct ion(ISD: :FREM, VT, Expand);
setOperationAct ion(ISD: :FPOW, VT, Expand); n(ISD:: EXTLOAD, MVT::f64, MVT::f16, Expand); ion(ISD: :FP16_TO_ FP, MVT::f64, Expand); ion(ISD: :FP_TO_ FP16, MVT::f64, Expand); n(ISD:: EXTLOAD, MVT::f32, MVT::f16, Expand); ion(ISD: :FP16_TO_ FP, MVT::f32, Expand); ion(ISD: :FP_TO_ FP16, MVT::f32, Expand); tion(MVT: :f64, MVT::f16, Expand); tion(MVT: :f32, MVT::f16, Expand);
index 383393914a16.
--- a/llvm/
+++ b/llvm/
@@ -529,6 +529,14 @@ SystemZTargetLo
+ setLoadExtActio
+ setOperationAct
+ setOperationAct
+ setLoadExtActio
+ setOperationAct
+ setOperationAct
+ setTruncStoreAc
+ setTruncStoreAc
// Special treatment.
setOperationAct ion(ISD: :IS_FPCLASS, VT, Custom);