Skip to content
59 changes: 19 additions & 40 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,30 +678,6 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
return true;
}

static bool interp__builtin_parity(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.popcount() % 2, Call->getType());
return true;
}

static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(), Call->getType());
return true;
}

static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
APSInt Val = popToAPSInt(S, Call->getArg(0));
pushInteger(S, Val.reverseBits(), Call->getType());
return true;
}

static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
Expand Down Expand Up @@ -736,16 +712,6 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
return true;
}

static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
APSInt Value = popToAPSInt(S, Call->getArg(0));

uint64_t N = Value.countr_zero();
pushInteger(S, N == Value.getBitWidth() ? 0 : N + 1, Call->getType());
return true;
}

static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const CallExpr *Call) {
Expand Down Expand Up @@ -3158,18 +3124,25 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case Builtin::BI__builtin_parity:
case Builtin::BI__builtin_parityl:
case Builtin::BI__builtin_parityll:
return interp__builtin_parity(S, OpPC, Frame, Call);

return interp__builtin_elementwise_int_unaryop(
S, OpPC, Call, [](const APSInt &Val) -> APInt {
return APInt(Val.getBitWidth(), Val.popcount() % 2);
});
case Builtin::BI__builtin_clrsb:
case Builtin::BI__builtin_clrsbl:
case Builtin::BI__builtin_clrsbll:
return interp__builtin_clrsb(S, OpPC, Frame, Call);

return interp__builtin_elementwise_int_unaryop(
S, OpPC, Call, [](const APSInt &Val) -> APInt {
return APInt(Val.getBitWidth(),
Val.getBitWidth() - Val.getSignificantBits());
});
case Builtin::BI__builtin_bitreverse8:
case Builtin::BI__builtin_bitreverse16:
case Builtin::BI__builtin_bitreverse32:
case Builtin::BI__builtin_bitreverse64:
return interp__builtin_bitreverse(S, OpPC, Frame, Call);
return interp__builtin_elementwise_int_unaryop(
S, OpPC, Call,
[](const APSInt &Val) -> APInt { return Val.reverseBits(); });

case Builtin::BI__builtin_classify_type:
return interp__builtin_classify_type(S, OpPC, Frame, Call);
Expand Down Expand Up @@ -3209,7 +3182,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
case Builtin::BI__builtin_ffs:
case Builtin::BI__builtin_ffsl:
case Builtin::BI__builtin_ffsll:
return interp__builtin_ffs(S, OpPC, Frame, Call);
return interp__builtin_elementwise_int_unaryop(
S, OpPC, Call, [](const APSInt &Val) {
return APInt(Val.getBitWidth(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a variable for Val.countTrainlingZeros().

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or just check if Val is zero - either is fine

(Val.countTrailingZeros() == Val.getBitWidth())
? 0u
: (Val.countTrailingZeros() + 1u));
});

case Builtin::BIaddressof:
case Builtin::BI__addressof:
Expand Down