================ @@ -12696,6 +12696,59 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return BuiltinOp == Builtin::BI__atomic_always_lock_free ? Success(0, E) : Error(E); } + case Builtin::BI__builtin_addcb: + case Builtin::BI__builtin_addcs: + case Builtin::BI__builtin_addc: + case Builtin::BI__builtin_addcl: + case Builtin::BI__builtin_addcll: + case Builtin::BI__builtin_subcb: + case Builtin::BI__builtin_subcs: + case Builtin::BI__builtin_subc: + case Builtin::BI__builtin_subcl: + case Builtin::BI__builtin_subcll: { + LValue CarryOutLValue; + APSInt LHS, RHS, CarryIn, CarryOut, Result; + QualType ResultType = E->getArg(0)->getType(); + if (!EvaluateInteger(E->getArg(0), LHS, Info) || + !EvaluateInteger(E->getArg(1), RHS, Info) || + !EvaluateInteger(E->getArg(2), CarryIn, Info) || + !EvaluatePointer(E->getArg(3), CarryOutLValue, Info)) + return false; + // Copy the number of bits and sign + Result = LHS; + CarryOut = LHS; + + bool FirstOverflowed = false; + bool SecondOverflowed = false; + switch (BuiltinOp) { + default: + llvm_unreachable("Invalid value for BuiltinOp"); + case Builtin::BI__builtin_addcb: + case Builtin::BI__builtin_addcs: + case Builtin::BI__builtin_addc: + case Builtin::BI__builtin_addcl: + case Builtin::BI__builtin_addcll: + Result = + LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed); + break; + case Builtin::BI__builtin_subcb: + case Builtin::BI__builtin_subcs: + case Builtin::BI__builtin_subc: + case Builtin::BI__builtin_subcl: + case Builtin::BI__builtin_subcll: + Result = + LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed); + break; + } + + // It is possible for both overflows to happen but CGBuiltin uses an OR so + // this is consistent ---------------- AaronBallman wrote:
```suggestion // this is consistent. ``` https://github.com/llvm/llvm-project/pull/81656 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits