Author: Timm Bäder Date: 2024-02-26T16:46:23+01:00 New Revision: 264d828ea6399c31c210b67a050fbf084634da6a
URL: https://github.com/llvm/llvm-project/commit/264d828ea6399c31c210b67a050fbf084634da6a DIFF: https://github.com/llvm/llvm-project/commit/264d828ea6399c31c210b67a050fbf084634da6a.diff LOG: [clang][Interp][NFC] Redo returning values from builtin functions Instead of having retInt/retLong/retSizeT/etc., just add retInteger, which takes an APSInt and returns it in form of the given QualType. This makes the code a little neater, but is also necessary since some builtins have a different return type with -fms-extensions. Added: Modified: clang/lib/AST/Interp/InterpBuiltin.cpp clang/test/CodeGen/ms-intrinsics-other.c Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 2fb076d7793a8d..8f45c789296b66 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -62,97 +62,32 @@ static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { return R; } -/// Pushes \p Val to the stack, as a target-dependent 'int'. -static void pushInt(InterpState &S, int32_t Val) { - PrimType IntType = getIntPrimType(S); - if (IntType == PT_Sint32) - S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val)); - else if (IntType == PT_Sint16) - S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val)); - else - llvm_unreachable("Int isn't 16 or 32 bit?"); -} - -static void pushAPSInt(InterpState &S, const APSInt &Val) { - bool Signed = Val.isSigned(); - - if (Signed) { - switch (Val.getBitWidth()) { - case 64: - S.Stk.push<Integral<64, true>>( - Integral<64, true>::from(Val.getSExtValue())); - break; - case 32: - S.Stk.push<Integral<32, true>>( - Integral<32, true>::from(Val.getSExtValue())); - break; - case 16: - S.Stk.push<Integral<16, true>>( - Integral<16, true>::from(Val.getSExtValue())); - break; - case 8: - S.Stk.push<Integral<8, true>>( - Integral<8, true>::from(Val.getSExtValue())); - break; - default: - llvm_unreachable("Invalid integer bitwidth"); - } - return; - } - - // Unsigned. - switch (Val.getBitWidth()) { - case 64: - S.Stk.push<Integral<64, false>>( - Integral<64, false>::from(Val.getZExtValue())); - break; - case 32: - S.Stk.push<Integral<32, false>>( - Integral<32, false>::from(Val.getZExtValue())); - break; - case 16: - S.Stk.push<Integral<16, false>>( - Integral<16, false>::from(Val.getZExtValue())); - break; - case 8: - S.Stk.push<Integral<8, false>>( - Integral<8, false>::from(Val.getZExtValue())); - break; - default: - llvm_unreachable("Invalid integer bitwidth"); +/// Pushes \p Val on the stack as the type given by \p QT. +static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) { + assert(QT->isSignedIntegerOrEnumerationType() || + QT->isUnsignedIntegerOrEnumerationType()); + std::optional<PrimType> T = S.getContext().classify(QT); + assert(T); + + if (QT->isSignedIntegerOrEnumerationType()) { + int64_t V = Val.getSExtValue(); + INT_TYPE_SWITCH(*T, { S.Stk.push<T>(T::from(V)); }); + } else { + assert(QT->isUnsignedIntegerOrEnumerationType()); + uint64_t V = Val.getZExtValue(); + INT_TYPE_SWITCH(*T, { S.Stk.push<T>(T::from(V)); }); } } -/// Pushes \p Val to the stack, as a target-dependent 'long'. -static void pushLong(InterpState &S, int64_t Val) { - PrimType LongType = getLongPrimType(S); - if (LongType == PT_Sint64) - S.Stk.push<Integral<64, true>>(Integral<64, true>::from(Val)); - else if (LongType == PT_Sint32) - S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val)); - else if (LongType == PT_Sint16) - S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val)); +template <typename T> +static void pushInteger(InterpState &S, T Val, QualType QT) { + if constexpr (std::is_same_v<T, APInt>) + pushInteger(S, APSInt(Val, !std::is_signed_v<T>), QT); else - llvm_unreachable("Long isn't 16, 32 or 64 bit?"); -} - -static void pushSizeT(InterpState &S, uint64_t Val) { - const TargetInfo &TI = S.getCtx().getTargetInfo(); - unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); - - switch (SizeTWidth) { - case 64: - S.Stk.push<Integral<64, false>>(Integral<64, false>::from(Val)); - break; - case 32: - S.Stk.push<Integral<32, false>>(Integral<32, false>::from(Val)); - break; - case 16: - S.Stk.push<Integral<16, false>>(Integral<16, false>::from(Val)); - break; - default: - llvm_unreachable("We don't handle this size_t size."); - } + pushInteger(S, + APSInt(APInt(sizeof(T) * 8, Val, std::is_signed_v<T>), + !std::is_signed_v<T>), + QT); } static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value) { @@ -188,7 +123,8 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, } static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame) { + const InterpFrame *Frame, + const CallExpr *Call) { const Pointer &A = getParam<Pointer>(Frame, 0); const Pointer &B = getParam<Pointer>(Frame, 1); @@ -222,12 +158,13 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, break; } - pushInt(S, Result); + pushInteger(S, Result, Call->getType()); return true; } static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame) { + const InterpFrame *Frame, + const CallExpr *Call) { const Pointer &StrPtr = getParam<Pointer>(Frame, 0); if (!CheckArray(S, OpPC, StrPtr)) @@ -253,7 +190,8 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, break; } - pushSizeT(S, Len); + pushInteger(S, Len, Call->getType()); + return true; } @@ -383,68 +321,71 @@ static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, /// take a float, double, long double, etc. /// But for us, that's all a Floating anyway. static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, const Function *F) { + const InterpFrame *Frame, const Function *F, + const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isNan()); + pushInteger(S, Arg.isNan(), Call->getType()); return true; } static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *F) { + const Function *F, + const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isSignaling()); + pushInteger(S, Arg.isSignaling(), Call->getType()); return true; } static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *F, - bool CheckSign) { + bool CheckSign, const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); bool IsInf = Arg.isInf(); if (CheckSign) - pushInt(S, IsInf ? (Arg.isNegative() ? -1 : 1) : 0); + pushInteger(S, IsInf ? (Arg.isNegative() ? -1 : 1) : 0, Call->getType()); else - pushInt(S, Arg.isInf()); + pushInteger(S, Arg.isInf(), Call->getType()); return true; } static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *F) { + const Function *F, const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isFinite()); + pushInteger(S, Arg.isFinite(), Call->getType()); return true; } static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *F) { + const Function *F, const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isNormal()); + pushInteger(S, Arg.isNormal(), Call->getType()); return true; } static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *F) { + const Function *F, + const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isDenormal()); + pushInteger(S, Arg.isDenormal(), Call->getType()); return true; } static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, - const InterpFrame *Frame, - const Function *F) { + const InterpFrame *Frame, const Function *F, + const CallExpr *Call) { const Floating &Arg = S.Stk.peek<Floating>(); - pushInt(S, Arg.isZero()); + pushInteger(S, Arg.isZero(), Call->getType()); return true; } @@ -461,7 +402,7 @@ static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, int32_t Result = static_cast<int32_t>((F.classify() & FPClassArg).getZExtValue()); - pushInt(S, Result); + pushInteger(S, Result, Call->getType()); return true; } @@ -469,7 +410,8 @@ static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, /// Five int values followed by one floating value. static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, - const Function *Func) { + const Function *Func, + const CallExpr *Call) { const Floating &Val = S.Stk.peek<Floating>(); unsigned Index; @@ -495,7 +437,7 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, align(primSize(PT_Float)) + ((1 + (4 - Index)) * align(IntSize)); APSInt I = peekToAPSInt(S.Stk, getIntPrimType(S), Offset); - pushInt(S, I.getZExtValue()); + pushInteger(S, I, Call->getType()); return true; } @@ -517,9 +459,12 @@ static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call) { + + Func->getDecl()->dump(); + PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); APSInt Val = peekToAPSInt(S.Stk, ArgT); - pushInt(S, Val.popcount()); + pushInteger(S, APSInt(APInt(32, Val.popcount())), Call->getType()); return true; } @@ -528,7 +473,7 @@ static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, const Function *Func, const CallExpr *Call) { PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); APSInt Val = peekToAPSInt(S.Stk, ArgT); - pushInt(S, Val.popcount() % 2); + pushInteger(S, Val.popcount() % 2, Call->getType()); return true; } @@ -537,7 +482,7 @@ static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, const Function *Func, const CallExpr *Call) { PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); APSInt Val = peekToAPSInt(S.Stk, ArgT); - pushInt(S, Val.getBitWidth() - Val.getSignificantBits()); + pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(), Call->getType()); return true; } @@ -547,7 +492,8 @@ static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, const CallExpr *Call) { PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); APSInt Val = peekToAPSInt(S.Stk, ArgT); - pushAPSInt(S, APSInt(Val.reverseBits(), /*IsUnsigned=*/true)); + // pushAPSInt(S, APSInt(Val.reverseBits(), /*IsUnsigned=*/true)); + pushInteger(S, Val.reverseBits(), Call->getType()); return true; } @@ -562,7 +508,7 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, GCCTypeClass ResultClass = EvaluateBuiltinClassifyType(Arg->getType(), S.getLangOpts()); int32_t ReturnVal = static_cast<int32_t>(ResultClass); - pushInt(S, ReturnVal); + pushInteger(S, ReturnVal, Call->getType()); return true; } @@ -582,7 +528,7 @@ static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, Offset += align(primSize(PT_Float)); APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset); - pushLong(S, Val.getSExtValue()); + pushInteger(S, Val, Call->getType()); return true; } @@ -605,7 +551,8 @@ static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())), /*IsUnsigned=*/true); - pushAPSInt(S, Result); + // pushAPSInt(S, Result); + pushInteger(S, Result, Call->getType()); return true; } @@ -616,7 +563,7 @@ static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, APSInt Value = peekToAPSInt(S.Stk, ArgT); uint64_t N = Value.countr_zero(); - pushInt(S, N == Value.getBitWidth() ? 0 : N + 1); + pushInteger(S, N == Value.getBitWidth() ? 0 : N + 1, Call->getType()); return true; } @@ -659,7 +606,7 @@ static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, int Result = S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue()); - pushInt(S, Result); + pushInteger(S, Result, Call->getType()); return true; } @@ -837,7 +784,8 @@ static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, CarryOutPtr.initialize(); assert(Call->getType() == Call->getArg(0)->getType()); - pushAPSInt(S, Result); + // pushAPSInt(S, Result); + pushInteger(S, Result, Call->getType()); return true; } @@ -857,7 +805,7 @@ static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, if (ZeroIsUndefined && Val == 0) return false; - pushInt(S, Val.countl_zero()); + pushInteger(S, APSInt(APInt(32, Val.countl_zero())), Call->getType()); return true; } @@ -870,7 +818,7 @@ static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, if (Val == 0) return false; - pushInt(S, Val.countr_zero()); + pushInteger(S, Val.countr_zero(), Call->getType()); return true; } @@ -972,11 +920,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, case Builtin::BI__assume: break; case Builtin::BI__builtin_strcmp: - if (!interp__builtin_strcmp(S, OpPC, Frame)) + if (!interp__builtin_strcmp(S, OpPC, Frame, Call)) return false; break; case Builtin::BI__builtin_strlen: - if (!interp__builtin_strlen(S, OpPC, Frame)) + if (!interp__builtin_strlen(S, OpPC, Frame, Call)) return false; break; case Builtin::BI__builtin_nan: @@ -1036,38 +984,38 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, break; case Builtin::BI__builtin_isnan: - if (!interp__builtin_isnan(S, OpPC, Frame, F)) + if (!interp__builtin_isnan(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_issignaling: - if (!interp__builtin_issignaling(S, OpPC, Frame, F)) + if (!interp__builtin_issignaling(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_isinf: - if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false)) + if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false, Call)) return false; break; case Builtin::BI__builtin_isinf_sign: - if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true)) + if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true, Call)) return false; break; case Builtin::BI__builtin_isfinite: - if (!interp__builtin_isfinite(S, OpPC, Frame, F)) + if (!interp__builtin_isfinite(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_isnormal: - if (!interp__builtin_isnormal(S, OpPC, Frame, F)) + if (!interp__builtin_isnormal(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_issubnormal: - if (!interp__builtin_issubnormal(S, OpPC, Frame, F)) + if (!interp__builtin_issubnormal(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_iszero: - if (!interp__builtin_iszero(S, OpPC, Frame, F)) + if (!interp__builtin_iszero(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_isfpclass: @@ -1075,7 +1023,7 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; case Builtin::BI__builtin_fpclassify: - if (!interp__builtin_fpclassify(S, OpPC, Frame, F)) + if (!interp__builtin_fpclassify(S, OpPC, Frame, F, Call)) return false; break; diff --git a/clang/test/CodeGen/ms-intrinsics-other.c b/clang/test/CodeGen/ms-intrinsics-other.c index 36c40dddcbb4f5..189000d3213ac1 100644 --- a/clang/test/CodeGen/ms-intrinsics-other.c +++ b/clang/test/CodeGen/ms-intrinsics-other.c @@ -1,38 +1,38 @@ // RUN: %clang_cc1 -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple x86_64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple x86_64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple x86_64--linux -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple x86_64--linux -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple aarch64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple aarch64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM-ARM64 // RUN: %clang_cc1 -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple aarch64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple aarch64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM // RUN: %clang_cc1 -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple armv7--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple armv7--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM // RUN: %clang_cc1 -x c++ -std=c++11 \ // RUN: -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple x86_64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple x86_64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -x c++ -std=c++11 \ // RUN: -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple x86_64--linux -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple x86_64--linux -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s // RUN: %clang_cc1 -x c++ -std=c++11 \ // RUN: -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple aarch64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple aarch64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM-ARM64 // RUN: %clang_cc1 -x c++ -std=c++11 \ // RUN: -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple aarch64--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple aarch64--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM // RUN: %clang_cc1 -x c++ -std=c++11 \ // RUN: -ffreestanding -fms-extensions -Wno-implicit-function-declaration \ -// RUN: -triple armv7--darwin -Oz -emit-llvm %s -o - \ +// RUN: -fexperimental-new-constant-interpreter -triple armv7--darwin -Oz -emit-llvm %s -o - \ // RUN: | FileCheck %s --check-prefix=CHECK-ARM // LP64 targets use 'long' as 'int' for MS intrinsics (-fms-extensions) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits