diff options
author | Timm Baeder <tbaeder@redhat.com> | 2025-06-20 18:06:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-20 18:06:01 +0200 |
commit | 32fc625a3fa27fa325c75b0fc841db4ce8e06805 (patch) | |
tree | b71a99d6cf02373ce3c92dcda344ef1d6f0fef12 /clang/lib/AST/ByteCode/InterpBuiltin.cpp | |
parent | 151ee0faad427651304b51b8af77704be26bb485 (diff) | |
download | llvm-32fc625a3fa27fa325c75b0fc841db4ce8e06805.zip llvm-32fc625a3fa27fa325c75b0fc841db4ce8e06805.tar.gz llvm-32fc625a3fa27fa325c75b0fc841db4ce8e06805.tar.bz2 |
Reapply "Reapply "[clang][bytecode] Allocate IntegralAP and Floating … (#145014)
…types usi… (#144676)"
This reverts commit 68471d29eed2c49f9b439e505b3f24d387d54f97.
IntegralAP contains a union:
union {
uint64_t *Memory = nullptr;
uint64_t Val;
};
On 64bit systems, both Memory and Val have the same size. However, on 32
bit system, Val is 64bit and Memory only 32bit. Which means the default
initializer for Memory will only zero half of Val. We fixed this by
zero-initializing Val explicitly in the IntegralAP(unsigned BitWidth)
constructor.
See also the discussion in
https://github.com/llvm/llvm-project/pull/144246
Diffstat (limited to 'clang/lib/AST/ByteCode/InterpBuiltin.cpp')
-rw-r--r-- | clang/lib/AST/ByteCode/InterpBuiltin.cpp | 55 |
1 files changed, 43 insertions, 12 deletions
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index d01e3d0..5304bd7 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -57,6 +57,21 @@ static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) { assert(T); unsigned BitWidth = S.getASTContext().getTypeSize(QT); + + if (T == PT_IntAPS) { + auto Result = S.allocAP<IntegralAP<true>>(BitWidth); + Result.copy(Val); + S.Stk.push<IntegralAP<true>>(Result); + return; + } + + if (T == PT_IntAP) { + auto Result = S.allocAP<IntegralAP<false>>(BitWidth); + Result.copy(Val); + S.Stk.push<IntegralAP<false>>(Result); + return; + } + if (QT->isSignedIntegerOrEnumerationType()) { int64_t V = Val.getSExtValue(); INT_TYPE_SWITCH(*T, { S.Stk.push<T>(T::from(V, BitWidth)); }); @@ -327,13 +342,13 @@ static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, S.getASTContext().getFloatTypeSemantics( Call->getDirectCallee()->getReturnType()); - Floating Result; + Floating Result = S.allocFloat(TargetSemantics); if (S.getASTContext().getTargetInfo().isNan2008()) { if (Signaling) - Result = Floating( + Result.copy( llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); else - Result = Floating( + Result.copy( llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); } else { // Prior to IEEE 754-2008, architectures were allowed to choose whether @@ -342,10 +357,10 @@ static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as // sNaN. This is now known as "legacy NaN" encoding. if (Signaling) - Result = Floating( + Result.copy( llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); else - Result = Floating( + Result.copy( llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); } @@ -360,7 +375,9 @@ static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, S.getASTContext().getFloatTypeSemantics( Call->getDirectCallee()->getReturnType()); - S.Stk.push<Floating>(Floating::getInf(TargetSemantics)); + Floating Result = S.allocFloat(TargetSemantics); + Result.copy(APFloat::getInf(TargetSemantics)); + S.Stk.push<Floating>(Result); return true; } @@ -368,10 +385,12 @@ static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, const InterpFrame *Frame) { const Floating &Arg2 = S.Stk.pop<Floating>(); const Floating &Arg1 = S.Stk.pop<Floating>(); + Floating Result = S.allocFloat(Arg1.getSemantics()); APFloat Copy = Arg1.getAPFloat(); Copy.copySign(Arg2.getAPFloat()); - S.Stk.push<Floating>(Floating(Copy)); + Result.copy(Copy); + S.Stk.push<Floating>(Result); return true; } @@ -380,11 +399,13 @@ static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); + Floating Result = S.allocFloat(LHS.getSemantics()); if (IsNumBuiltin) - S.Stk.push<Floating>(llvm::minimumnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(llvm::minimumnum(LHS.getAPFloat(), RHS.getAPFloat())); else - S.Stk.push<Floating>(minnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(minnum(LHS.getAPFloat(), RHS.getAPFloat())); + S.Stk.push<Floating>(Result); return true; } @@ -392,11 +413,13 @@ static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, bool IsNumBuiltin) { const Floating &RHS = S.Stk.pop<Floating>(); const Floating &LHS = S.Stk.pop<Floating>(); + Floating Result = S.allocFloat(LHS.getSemantics()); if (IsNumBuiltin) - S.Stk.push<Floating>(llvm::maximumnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(llvm::maximumnum(LHS.getAPFloat(), RHS.getAPFloat())); else - S.Stk.push<Floating>(maxnum(LHS.getAPFloat(), RHS.getAPFloat())); + Result.copy(maxnum(LHS.getAPFloat(), RHS.getAPFloat())); + S.Stk.push<Floating>(Result); return true; } @@ -571,8 +594,16 @@ static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, const InterpFrame *Frame) { const Floating &Val = S.Stk.pop<Floating>(); + APFloat F = Val.getAPFloat(); + if (!F.isNegative()) { + S.Stk.push<Floating>(Val); + return true; + } - S.Stk.push<Floating>(Floating::abs(Val)); + Floating Result = S.allocFloat(Val.getSemantics()); + F.changeSign(); + Result.copy(F); + S.Stk.push<Floating>(Result); return true; } |