[llvm] [RISCV][GISel] Lower G_SADDE (PR #156865)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 9 04:56:21 PDT 2025


================
@@ -9288,6 +9290,35 @@ LegalizerHelper::lowerSADDO_SSUBO(MachineInstr &MI) {
   return Legalized;
 }
 
+LegalizerHelper::LegalizeResult LegalizerHelper::lowerSADDE(MachineInstr &MI) {
+  auto [Res, OvOut, LHS, RHS, CarryIn] = MI.getFirst5Regs();
+  const LLT Ty = MRI.getType(Res);
+  const LLT BoolTy = MRI.getType(OvOut);
+
+  // Step 1: tmp = LHS + RHS
+  auto Tmp = MIRBuilder.buildAdd(Ty, LHS, RHS);
+
+  // ov0 = (tmp < lhs) XOR (rhs < 0)
+  auto TmpLtLHS = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, Tmp, LHS);
+  auto Zero = MIRBuilder.buildConstant(Ty, 0);
+  auto RHSLt0 = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, RHS, Zero);
+  auto Ov0 = MIRBuilder.buildXor(BoolTy, TmpLtLHS, RHSLt0);
+
+  // Step 2: sum = tmp + zext(CarryIn)
+  auto CarryInZ = MIRBuilder.buildZExt(Ty, CarryIn);
+  MIRBuilder.buildAdd(Res, Tmp, CarryInZ);
+
+  // ov1 = CarryIn & (sum < tmp)
+  auto SumLtTmp = MIRBuilder.buildICmp(CmpInst::ICMP_SLT, BoolTy, Res, Tmp);
+  auto Ov1 = MIRBuilder.buildAnd(BoolTy, SumLtTmp, CarryIn);
+
+  // ov = ov0 | ov1
+  MIRBuilder.buildOr(OvOut, Ov0, Ov1);
+
+  MI.eraseFromParent();
----------------
woruyu wrote:

For me:
LHS = -128 (0x80), RHS = -1 (0xFF), CarryIn = 1,
ov0 = (tmp < lhs) ^ (rhs < 0) = false ^ true = true, so ov = true, but should be false

For review:
LHS = 0 (0x00), RHS = -1 (0xFF), CarryIn = 1, but ov = false ^ true = true, but should be false

I think:
sum = LHS + RHS + zext(CarryIn)
ov = msb((Sum ^ LHS) & (Sum ^ RHS))  -- just check signed bit
It is right?

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


More information about the llvm-commits mailing list