[llvm] [LoongArch] Fold constant condition for LoongArchISD::BRCOND (PR #215936)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 20:05:51 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-loongarch

Author: wanglei (wangleiat)

<details>
<summary>Changes</summary>

Fold constant condition for LoongArchISD::BRCOND during DAGCombine:
a false condition folds to the chain operand, and a true condition
folds to ISD::BR.

This prevents instruction selection failures when BRCOND is folded to a
constant condition.

Fixes: #<!-- -->215935


---
Full diff: https://github.com/llvm/llvm-project/pull/215936.diff


2 Files Affected:

- (modified) llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp (+18) 
- (added) llvm/test/CodeGen/LoongArch/pr215935.ll (+47) 


``````````diff
diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
index e4a369c096545..133fd9aa9011c 100644
--- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp
@@ -7300,6 +7300,22 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
   return false;
 }
 
+static SDValue performBRCONDCombine(SDNode *N, SelectionDAG &DAG,
+                                    TargetLowering::DAGCombinerInfo &DCI,
+                                    const LoongArchSubtarget &Subtarget) {
+  SDValue Chain = N->getOperand(0);
+  SDValue Cond = N->getOperand(1);
+  SDValue BB = N->getOperand(2);
+  SDLoc DL(N);
+
+  if (isNullConstantOrUndef(Cond))
+    return Chain;
+  if (isa<ConstantSDNode>(Cond))
+    return DAG.getNode(ISD::BR, DL, MVT::Other, Chain, BB);
+
+  return SDValue();
+}
+
 static SDValue performBR_CCCombine(SDNode *N, SelectionDAG &DAG,
                                    TargetLowering::DAGCombinerInfo &DCI,
                                    const LoongArchSubtarget &Subtarget) {
@@ -8698,6 +8714,8 @@ SDValue LoongArchTargetLowering::PerformDAGCombine(SDNode *N,
     return performFP_TO_INTCombine(N, DAG, DCI, Subtarget);
   case LoongArchISD::BITREV_W:
     return performBITREV_WCombine(N, DAG, DCI, Subtarget);
+  case LoongArchISD::BRCOND:
+    return performBRCONDCombine(N, DAG, DCI, Subtarget);
   case LoongArchISD::BR_CC:
     return performBR_CCCombine(N, DAG, DCI, Subtarget);
   case LoongArchISD::SELECT_CC:
diff --git a/llvm/test/CodeGen/LoongArch/pr215935.ll b/llvm/test/CodeGen/LoongArch/pr215935.ll
new file mode 100644
index 0000000000000..fcc3d322054c7
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/pr215935.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
+; RUN: llc --mtriple=loongarch64 -mattr=+lsx < %s | FileCheck %s
+
+define i64 @brcond_const_1(i64 %0) {
+; CHECK-LABEL: brcond_const_1:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    b .LBB0_2
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB0_2:
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
+  %2 = trunc i64 %0 to i32
+  %3 = trunc i64 %0 to i8
+  %4 = uitofp i8 %3 to double
+  %5 = and i32 %2, 255
+  %6 = uitofp i32 %5 to double
+  %7 = fcmp one double %4, %6
+  br i1 %7, label %8, label %9
+8:
+  ret i64 0
+9:
+  ret i64 1
+}
+
+define i64 @brcond_const_0(i64 %0) {
+; CHECK-LABEL: brcond_const_0:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:  # %bb.1:
+; CHECK-NEXT:    move $a0, $zero
+; CHECK-NEXT:    ret
+; CHECK-NEXT:  .LBB1_2:
+; CHECK-NEXT:    ori $a0, $zero, 1
+; CHECK-NEXT:    ret
+  %2 = trunc i64 %0 to i32
+  %3 = trunc i64 %0 to i8
+  %4 = uitofp i8 %3 to double
+  %5 = and i32 %2, 255
+  %6 = uitofp i32 %5 to double
+  %7 = fcmp oeq double %4, %6
+  br i1 %7, label %8, label %9
+8:
+  ret i64 0
+9:
+  ret i64 1
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/215936


More information about the llvm-commits mailing list