[llvm] [SystemZ] Fix assertion failures during DAG combine (PR #215027)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 8 14:07:56 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-systemz
Author: Jacob Young (jacobly0)
<details>
<summary>Changes</summary>
Previously this code would generate:
i16 = bitcast f16
i32 = truncate i16
Which would immediately assert due to the invalid truncate, but even with that fixed it would assert later due to the illegal i16. Instead, use the same lowering as `LowerOperationWrapper` for the bitcast.
---
Full diff: https://github.com/llvm/llvm-project/pull/215027.diff
2 Files Affected:
- (modified) llvm/lib/Target/SystemZ/SystemZISelLowering.cpp (+8-2)
- (added) llvm/test/CodeGen/SystemZ/fp-half-vector-abs.ll (+124)
``````````diff
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 710832525426b..1a72683b53f42 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -7632,8 +7632,14 @@ SDValue SystemZTargetLowering::combineExtract(const SDLoc &DL, EVT ResVT,
// We're extracting the low part of one operand of the BUILD_VECTOR.
Op = Op.getOperand(End / OpBytesPerElement - 1);
if (!Op.getValueType().isInteger()) {
- EVT VT = MVT::getIntegerVT(Op.getValueSizeInBits());
- Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
+ if (Op.getValueType() == MVT::f16) {
+ assert(Subtarget.hasVector() && "canTreatAsByteVector was true");
+ Op = SDValue(DAG.getMachineNode(SystemZ::LFER_16, DL, MVT::i32, Op),
+ 0);
+ } else {
+ EVT VT = MVT::getIntegerVT(Op.getValueSizeInBits());
+ Op = DAG.getNode(ISD::BITCAST, DL, VT, Op);
+ }
DCI.AddToWorklist(Op.getNode());
}
EVT VT = MVT::getIntegerVT(ResVT.getSizeInBits());
diff --git a/llvm/test/CodeGen/SystemZ/fp-half-vector-abs.ll b/llvm/test/CodeGen/SystemZ/fp-half-vector-abs.ll
new file mode 100644
index 0000000000000..7663518f1e122
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/fp-half-vector-abs.ll
@@ -0,0 +1,124 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z16 | FileCheck %s --check-prefix=VECTOR
+
+define <2 x half> @fabs_f16(<2 x half> %arg) {
+; CHECK-LABEL: fabs_f16:
+; CHECK: # %bb.0:
+; CHECK-NEXT: stmg %r12, %r15, 96(%r15)
+; CHECK-NEXT: .cfi_offset %r12, -64
+; CHECK-NEXT: .cfi_offset %r13, -56
+; CHECK-NEXT: .cfi_offset %r14, -48
+; CHECK-NEXT: .cfi_offset %r15, -40
+; CHECK-NEXT: aghi %r15, -184
+; CHECK-NEXT: .cfi_def_cfa_offset 344
+; CHECK-NEXT: std %f8, 176(%r15) # 8-byte Spill
+; CHECK-NEXT: std %f9, 168(%r15) # 8-byte Spill
+; CHECK-NEXT: std %f10, 160(%r15) # 8-byte Spill
+; CHECK-NEXT: .cfi_offset %f8, -168
+; CHECK-NEXT: .cfi_offset %f9, -176
+; CHECK-NEXT: .cfi_offset %f10, -184
+; CHECK-NEXT: ler %f8, %f2
+; CHECK-NEXT: ler %f10, %f0
+; CHECK-NEXT: lgdr %r0, %f8
+; CHECK-NEXT: srlg %r0, %r0, 48
+; CHECK-NEXT: lhr %r13, %r0
+; CHECK-NEXT: lgdr %r0, %f10
+; CHECK-NEXT: srlg %r0, %r0, 48
+; CHECK-NEXT: lcdfr %f0, %f0
+; CHECK-NEXT: lhr %r12, %r0
+; CHECK-NEXT: brasl %r14, __extendhfsf2 at PLT
+; CHECK-NEXT: ler %f9, %f0
+; CHECK-NEXT: ler %f0, %f10
+; CHECK-NEXT: brasl %r14, __extendhfsf2 at PLT
+; CHECK-NEXT: lcdfr %f10, %f8
+; CHECK-NEXT: cijl %r12, 0, .LBB0_2
+; CHECK-NEXT: # %bb.1:
+; CHECK-NEXT: ler %f9, %f0
+; CHECK-NEXT: .LBB0_2:
+; CHECK-NEXT: ler %f0, %f9
+; CHECK-NEXT: brasl %r14, __truncsfhf2 at PLT
+; CHECK-NEXT: ler %f9, %f0
+; CHECK-NEXT: ler %f0, %f10
+; CHECK-NEXT: brasl %r14, __extendhfsf2 at PLT
+; CHECK-NEXT: ler %f10, %f0
+; CHECK-NEXT: ler %f0, %f8
+; CHECK-NEXT: brasl %r14, __extendhfsf2 at PLT
+; CHECK-NEXT: cijl %r13, 0, .LBB0_4
+; CHECK-NEXT: # %bb.3:
+; CHECK-NEXT: ler %f10, %f0
+; CHECK-NEXT: .LBB0_4:
+; CHECK-NEXT: ler %f0, %f10
+; CHECK-NEXT: brasl %r14, __truncsfhf2 at PLT
+; CHECK-NEXT: ler %f2, %f0
+; CHECK-NEXT: ler %f0, %f9
+; CHECK-NEXT: ld %f8, 176(%r15) # 8-byte Reload
+; CHECK-NEXT: ld %f9, 168(%r15) # 8-byte Reload
+; CHECK-NEXT: ld %f10, 160(%r15) # 8-byte Reload
+; CHECK-NEXT: lmg %r12, %r15, 280(%r15)
+; CHECK-NEXT: br %r14
+;
+; VECTOR-LABEL: fabs_f16:
+; VECTOR: # %bb.0:
+; VECTOR-NEXT: stmg %r12, %r15, 96(%r15)
+; VECTOR-NEXT: .cfi_offset %r12, -64
+; VECTOR-NEXT: .cfi_offset %r13, -56
+; VECTOR-NEXT: .cfi_offset %r14, -48
+; VECTOR-NEXT: .cfi_offset %r15, -40
+; VECTOR-NEXT: aghi %r15, -208
+; VECTOR-NEXT: .cfi_def_cfa_offset 368
+; VECTOR-NEXT: std %f8, 200(%r15) # 8-byte Spill
+; VECTOR-NEXT: std %f9, 192(%r15) # 8-byte Spill
+; VECTOR-NEXT: .cfi_offset %f8, -168
+; VECTOR-NEXT: .cfi_offset %f9, -176
+; VECTOR-NEXT: vlr %v0, %v24
+; VECTOR-NEXT: vlgvh %r0, %v0, 0
+; VECTOR-NEXT: vreph %v1, %v24, 1
+; VECTOR-NEXT: lhr %r13, %r0
+; VECTOR-NEXT: vlgvh %r0, %v1, 0
+; VECTOR-NEXT: lcdfr %f0, %f1
+; VECTOR-NEXT: vst %v24, 176(%r15), 3 # 16-byte Spill
+; VECTOR-NEXT: vst %v1, 160(%r15), 3 # 16-byte Spill
+; VECTOR-NEXT: lhr %r12, %r0
+; VECTOR-NEXT: brasl %r14, __extendhfsf2 at PLT
+; VECTOR-NEXT: ldr %f8, %f0
+; VECTOR-NEXT: vl %v0, 160(%r15), 3 # 16-byte Reload
+; VECTOR-NEXT: # kill: def $f0h killed $f0h killed $v0
+; VECTOR-NEXT: brasl %r14, __extendhfsf2 at PLT
+; VECTOR-NEXT: vl %v1, 176(%r15), 3 # 16-byte Reload
+; VECTOR-NEXT: lcdfr %f9, %f1
+; VECTOR-NEXT: cijl %r12, 0, .LBB0_2
+; VECTOR-NEXT: # %bb.1:
+; VECTOR-NEXT: ldr %f8, %f0
+; VECTOR-NEXT: .LBB0_2:
+; VECTOR-NEXT: ldr %f0, %f8
+; VECTOR-NEXT: brasl %r14, __truncsfhf2 at PLT
+; VECTOR-NEXT: # kill: def $f0h killed $f0h def $v0
+; VECTOR-NEXT: vst %v0, 160(%r15), 3 # 16-byte Spill
+; VECTOR-NEXT: ldr %f0, %f9
+; VECTOR-NEXT: brasl %r14, __extendhfsf2 at PLT
+; VECTOR-NEXT: ldr %f8, %f0
+; VECTOR-NEXT: vl %v0, 176(%r15), 3 # 16-byte Reload
+; VECTOR-NEXT: # kill: def $f0h killed $f0h killed $v0
+; VECTOR-NEXT: brasl %r14, __extendhfsf2 at PLT
+; VECTOR-NEXT: cijl %r13, 0, .LBB0_4
+; VECTOR-NEXT: # %bb.3:
+; VECTOR-NEXT: ldr %f8, %f0
+; VECTOR-NEXT: .LBB0_4:
+; VECTOR-NEXT: ldr %f0, %f8
+; VECTOR-NEXT: brasl %r14, __truncsfhf2 at PLT
+; VECTOR-NEXT: vl %v1, 160(%r15), 3 # 16-byte Reload
+; VECTOR-NEXT: # kill: def $f0h killed $f0h def $v0
+; VECTOR-NEXT: vmrhh %v0, %v0, %v1
+; VECTOR-NEXT: ld %f8, 200(%r15) # 8-byte Reload
+; VECTOR-NEXT: ld %f9, 192(%r15) # 8-byte Reload
+; VECTOR-NEXT: vmrhf %v0, %v0, %v0
+; VECTOR-NEXT: vmrhg %v24, %v0, %v0
+; VECTOR-NEXT: lmg %r12, %r15, 304(%r15)
+; VECTOR-NEXT: br %r14
+ %bits = bitcast <2 x half> %arg to <2 x i16>
+ %is_neg = icmp slt <2 x i16> %bits, zeroinitializer
+ %neg = fneg <2 x half> %arg
+ %res = select <2 x i1> %is_neg, <2 x half> %neg, <2 x half> %arg
+ ret <2 x half> %res
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/215027
More information about the llvm-commits
mailing list