https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/196695
Backport 6da957d8cbaffca03f00c747e360dbbdbada556e Requested by: @alexrp >From fd10d8f310777d36be24feb265ee6b57fac52561 Mon Sep 17 00:00:00 2001 From: Tony Varghese <[email protected]> Date: Sat, 9 May 2026 12:15:03 +0530 Subject: [PATCH] [DAGTypeLegalizer] Add missing BR_CC handler for soft-promoted half operands (#196214) `SoftPromoteHalfOperand` had no case for `ISD::BR_CC`, causing a crash when a half-typed `fcmp` result fed directly into a conditional branch. All other comparison-related nodes (`SETCC, SELECT_CC`) were already handled. Add `SoftPromoteHalfOp_BR_CC` following the same pattern as `SoftPromoteHalfOp_SELECT_CC`. Fixes #195562 --------- Co-authored-by: Tony Varghese <[email protected]> (cherry picked from commit 6da957d8cbaffca03f00c747e360dbbdbada556e) --- .../SelectionDAG/LegalizeFloatTypes.cpp | 27 +++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + .../PowerPC/soft-promote-half-br-cc.ll | 162 ++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 llvm/test/CodeGen/PowerPC/soft-promote-half-br-cc.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 23c6b2085cb0c..9188abdea4535 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -3851,6 +3851,9 @@ bool DAGTypeLegalizer::SoftPromoteHalfOperand(SDNode *N, unsigned OpNo) { case ISD::STRICT_FP_EXTEND: case ISD::FP_EXTEND: Res = SoftPromoteHalfOp_FP_EXTEND(N); break; case ISD::SELECT_CC: Res = SoftPromoteHalfOp_SELECT_CC(N, OpNo); break; + case ISD::BR_CC: + Res = SoftPromoteHalfOp_BR_CC(N); + break; case ISD::SETCC: Res = SoftPromoteHalfOp_SETCC(N); break; case ISD::STORE: Res = SoftPromoteHalfOp_STORE(N, OpNo); break; case ISD::ATOMIC_STORE: @@ -3963,6 +3966,30 @@ SDValue DAGTypeLegalizer::SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N) { N->getOperand(1)); } +SDValue DAGTypeLegalizer::SoftPromoteHalfOp_BR_CC(SDNode *N) { + // ISD::BR_CC node: chain(0), condcode(1), LHS(2), RHS(3), dest(4) + // The comparison operands (LHS, RHS) are soft-promoted halfs. + SDValue Op0 = N->getOperand(2); + SDValue Op1 = N->getOperand(3); + SDLoc dl(N); + + EVT SVT = Op0.getValueType(); + EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), SVT); + + // Get the soft-promoted i16 values + Op0 = GetSoftPromotedHalf(Op0); + Op1 = GetSoftPromotedHalf(Op1); + + // Promote both comparison operands to the larger FP type. + unsigned PromotionOpcode = GetPromotionOpcode(SVT, NVT); + Op0 = DAG.getNode(PromotionOpcode, dl, NVT, Op0); + Op1 = DAG.getNode(PromotionOpcode, dl, NVT, Op1); + + // Create a new BR_CC node with promoted operands + return DAG.getNode(ISD::BR_CC, dl, MVT::Other, N->getOperand(0), + N->getOperand(1), Op0, Op1, N->getOperand(4)); +} + SDValue DAGTypeLegalizer::SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo) { assert(OpNo == 0 && "Can only soften the comparison values"); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 79f0129ea5bf6..aeacafa91103d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -855,6 +855,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer { SDValue SoftPromoteHalfOp_FP_TO_XINT_SAT(SDNode *N); SDValue SoftPromoteHalfOp_SETCC(SDNode *N); SDValue SoftPromoteHalfOp_SELECT_CC(SDNode *N, unsigned OpNo); + SDValue SoftPromoteHalfOp_BR_CC(SDNode *N); SDValue SoftPromoteHalfOp_STORE(SDNode *N, unsigned OpNo); SDValue SoftPromoteHalfOp_ATOMIC_STORE(SDNode *N, unsigned OpNo); SDValue SoftPromoteHalfOp_STACKMAP(SDNode *N, unsigned OpNo); diff --git a/llvm/test/CodeGen/PowerPC/soft-promote-half-br-cc.ll b/llvm/test/CodeGen/PowerPC/soft-promote-half-br-cc.ll new file mode 100644 index 0000000000000..2726e287f5df7 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/soft-promote-half-br-cc.ll @@ -0,0 +1,162 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr9 < %s | FileCheck %s --check-prefix=CHECK-P9 +; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu \ +; RUN: -mcpu=pwr8 < %s | FileCheck %s --check-prefix=CHECK-P8 + +; Basic comparison with branch +define i32 @test_br_cc_olt(half %a, half %b) nounwind { +; CHECK-P9-LABEL: test_br_cc_olt: +; CHECK-P9: # %bb.0: +; CHECK-P9-NEXT: clrlwi 3, 3, 16 +; CHECK-P9-NEXT: clrlwi 4, 4, 16 +; CHECK-P9-NEXT: mtfprwz 0, 4 +; CHECK-P9-NEXT: mtfprwz 1, 3 +; CHECK-P9-NEXT: xscvhpdp 0, 0 +; CHECK-P9-NEXT: xscvhpdp 1, 1 +; CHECK-P9-NEXT: fcmpu 0, 1, 0 +; CHECK-P9-NEXT: bge 0, .LBB0_2 +; CHECK-P9-NEXT: # %bb.1: # %if.then +; CHECK-P9-NEXT: li 3, 1 +; CHECK-P9-NEXT: blr +; CHECK-P9-NEXT: .LBB0_2: # %if.else +; CHECK-P9-NEXT: li 3, 0 +; CHECK-P9-NEXT: blr +; +; CHECK-P8-LABEL: test_br_cc_olt: +; CHECK-P8: # %bb.0: +; CHECK-P8-NEXT: mflr 0 +; CHECK-P8-NEXT: std 30, -24(1) # 8-byte Folded Spill +; CHECK-P8-NEXT: stfd 31, -8(1) # 8-byte Folded Spill +; CHECK-P8-NEXT: stdu 1, -64(1) +; CHECK-P8-NEXT: mr 30, 3 +; CHECK-P8-NEXT: clrldi 3, 4, 48 +; CHECK-P8-NEXT: std 0, 80(1) +; CHECK-P8-NEXT: bl __extendhfsf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: clrldi 3, 30, 48 +; CHECK-P8-NEXT: fmr 31, 1 +; CHECK-P8-NEXT: bl __extendhfsf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: fcmpu 0, 1, 31 +; CHECK-P8-NEXT: bge 0, .LBB0_2 +; CHECK-P8-NEXT: # %bb.1: # %if.then +; CHECK-P8-NEXT: li 3, 1 +; CHECK-P8-NEXT: b .LBB0_3 +; CHECK-P8-NEXT: .LBB0_2: # %if.else +; CHECK-P8-NEXT: li 3, 0 +; CHECK-P8-NEXT: .LBB0_3: # %if.then +; CHECK-P8-NEXT: addi 1, 1, 64 +; CHECK-P8-NEXT: ld 0, 16(1) +; CHECK-P8-NEXT: lfd 31, -8(1) # 8-byte Folded Reload +; CHECK-P8-NEXT: ld 30, -24(1) # 8-byte Folded Reload +; CHECK-P8-NEXT: mtlr 0 +; CHECK-P8-NEXT: blr + %cmp = fcmp olt half %a, %b + br i1 %cmp, label %if.then, label %if.else +if.then: + ret i32 1 +if.else: + ret i32 0 +} + +; Test with constant +define i32 @test_br_cc_constant(half %a) nounwind { +; CHECK-P9-LABEL: test_br_cc_constant: +; CHECK-P9: # %bb.0: +; CHECK-P9-NEXT: clrlwi 3, 3, 16 +; CHECK-P9-NEXT: xxlxor 1, 1, 1 +; CHECK-P9-NEXT: mtfprwz 0, 3 +; CHECK-P9-NEXT: xscvhpdp 0, 0 +; CHECK-P9-NEXT: fcmpu 0, 0, 1 +; CHECK-P9-NEXT: ble 0, .LBB1_2 +; CHECK-P9-NEXT: # %bb.1: # %if.then +; CHECK-P9-NEXT: li 3, 1 +; CHECK-P9-NEXT: blr +; CHECK-P9-NEXT: .LBB1_2: # %if.else +; CHECK-P9-NEXT: li 3, 0 +; CHECK-P9-NEXT: blr +; +; CHECK-P8-LABEL: test_br_cc_constant: +; CHECK-P8: # %bb.0: +; CHECK-P8-NEXT: mflr 0 +; CHECK-P8-NEXT: stdu 1, -32(1) +; CHECK-P8-NEXT: clrldi 3, 3, 48 +; CHECK-P8-NEXT: std 0, 48(1) +; CHECK-P8-NEXT: bl __extendhfsf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: xxlxor 0, 0, 0 +; CHECK-P8-NEXT: fcmpu 0, 1, 0 +; CHECK-P8-NEXT: ble 0, .LBB1_2 +; CHECK-P8-NEXT: # %bb.1: # %if.then +; CHECK-P8-NEXT: li 3, 1 +; CHECK-P8-NEXT: b .LBB1_3 +; CHECK-P8-NEXT: .LBB1_2: # %if.else +; CHECK-P8-NEXT: li 3, 0 +; CHECK-P8-NEXT: .LBB1_3: # %if.then +; CHECK-P8-NEXT: addi 1, 1, 32 +; CHECK-P8-NEXT: ld 0, 16(1) +; CHECK-P8-NEXT: mtlr 0 +; CHECK-P8-NEXT: blr + %cmp = fcmp ogt half %a, 0xH0000 + br i1 %cmp, label %if.then, label %if.else +if.then: + ret i32 1 +if.else: + ret i32 0 +} + +; vector reduction + branch +define fastcc i16 @test_vector_reduce_br(half %arg) nounwind { +; CHECK-P9-LABEL: test_vector_reduce_br: +; CHECK-P9: # %bb.0: +; CHECK-P9-NEXT: clrlwi 3, 3, 16 +; CHECK-P9-NEXT: xxlxor 1, 1, 1 +; CHECK-P9-NEXT: mtfprwz 0, 3 +; CHECK-P9-NEXT: xscvhpdp 0, 0 +; CHECK-P9-NEXT: fcmpu 0, 0, 1 +; CHECK-P9-NEXT: bc 12, 0, .LBB2_3 +; CHECK-P9-NEXT: # %bb.1: +; CHECK-P9-NEXT: fcmpu 0, 0, 0 +; CHECK-P9-NEXT: bc 12, 3, .LBB2_3 +; CHECK-P9-NEXT: # %bb.2: # %taken +; CHECK-P9-NEXT: li 3, 0 +; CHECK-P9-NEXT: blr +; CHECK-P9-NEXT: .LBB2_3: # %not_taken +; CHECK-P9-NEXT: li 3, 1 +; CHECK-P9-NEXT: blr +; +; CHECK-P8-LABEL: test_vector_reduce_br: +; CHECK-P8: # %bb.0: +; CHECK-P8-NEXT: mflr 0 +; CHECK-P8-NEXT: stdu 1, -32(1) +; CHECK-P8-NEXT: clrldi 3, 3, 48 +; CHECK-P8-NEXT: std 0, 48(1) +; CHECK-P8-NEXT: bl __extendhfsf2 +; CHECK-P8-NEXT: nop +; CHECK-P8-NEXT: xxlxor 0, 0, 0 +; CHECK-P8-NEXT: fcmpu 0, 1, 0 +; CHECK-P8-NEXT: bc 12, 0, .LBB2_3 +; CHECK-P8-NEXT: # %bb.1: +; CHECK-P8-NEXT: fcmpu 0, 1, 1 +; CHECK-P8-NEXT: bc 12, 3, .LBB2_3 +; CHECK-P8-NEXT: # %bb.2: # %taken +; CHECK-P8-NEXT: li 3, 0 +; CHECK-P8-NEXT: b .LBB2_4 +; CHECK-P8-NEXT: .LBB2_3: # %not_taken +; CHECK-P8-NEXT: li 3, 1 +; CHECK-P8-NEXT: .LBB2_4: # %taken +; CHECK-P8-NEXT: addi 1, 1, 32 +; CHECK-P8-NEXT: ld 0, 16(1) +; CHECK-P8-NEXT: mtlr 0 +; CHECK-P8-NEXT: blr + %reduce = tail call half @llvm.vector.reduce.fmin.v4f16(<4 x half> zeroinitializer) + %cmp = fcmp ole half %reduce, %arg + br i1 %cmp, label %taken, label %not_taken +taken: + ret i16 0 +not_taken: + ret i16 1 +} + +declare half @llvm.vector.reduce.fmin.v4f16(<4 x half>) _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
