Skip to content

Commit 581c015

Browse files
authored
[clang][bytecode] Implement fixed point negation (#110237)
1 parent d5dc508 commit 581c015

File tree

5 files changed

+24
-12
lines changed

5 files changed

+24
-12
lines changed

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,9 @@ bool Compiler<Emitter>::VisitFixedPointLiteral(const FixedPointLiteral *E) {
724724
assert(E->getType()->isFixedPointType());
725725
assert(classifyPrim(E) == PT_FixedPoint);
726726

727-
// FIXME: Semantics.
727+
auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
728728
APInt Value = E->getValue();
729-
return this->emitConstFixedPoint(Value, E);
729+
return this->emitConstFixedPoint(FixedPoint(Value, Sem), E);
730730
}
731731

732732
template <class Emitter>

clang/lib/AST/ByteCode/FixedPoint.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ namespace clang {
1717
namespace interp {
1818

1919
using APInt = llvm::APInt;
20+
using APSInt = llvm::APSInt;
2021

2122
/// Wrapper around fixed point types.
2223
class FixedPoint final {
2324
private:
2425
llvm::APFixedPoint V;
26+
FixedPoint(llvm::APFixedPoint &&V) : V(std::move(V)) {}
2527

2628
public:
27-
FixedPoint(APInt V)
28-
: V(V,
29-
llvm::FixedPointSemantics(V.getBitWidth(), 0, false, false, false)) {}
29+
FixedPoint(APInt V, llvm::FixedPointSemantics Sem) : V(V, Sem) {}
3030
// This needs to be default-constructible so llvm::endian::read works.
3131
FixedPoint()
3232
: V(APInt(0, 0ULL, false),
@@ -42,12 +42,22 @@ class FixedPoint final {
4242
void print(llvm::raw_ostream &OS) const { OS << V; }
4343

4444
APValue toAPValue(const ASTContext &) const { return APValue(V); }
45+
APSInt toAPSInt(unsigned BitWidth) const { return V.getValue(); }
46+
47+
unsigned bitWidth() const { return V.getWidth(); }
48+
bool isSigned() const { return V.isSigned(); }
4549

4650
ComparisonCategoryResult compare(const FixedPoint &Other) const {
4751
if (Other.V == V)
4852
return ComparisonCategoryResult::Equal;
4953
return ComparisonCategoryResult::Unordered;
5054
}
55+
56+
static bool neg(const FixedPoint &A, FixedPoint *R) {
57+
bool Overflow = false;
58+
*R = FixedPoint(A.V.negate(&Overflow));
59+
return Overflow;
60+
}
5161
};
5262

5363
inline FixedPoint getSwappedBytes(FixedPoint F) { return F; }

clang/lib/AST/ByteCode/Opcodes.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def PtrTypeClass : TypeClass {
106106
}
107107

108108
def NonPtrTypeClass : TypeClass {
109-
let Types = !listconcat(IntegerTypeClass.Types, [Bool], [Float]);
109+
let Types = !listconcat(IntegerTypeClass.Types, [Bool], [Float], [FixedPoint]);
110110
}
111111

112112
def AllTypeClass : TypeClass {

clang/lib/AST/ByteCode/PrimType.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ enum PrimType : unsigned {
4343
PT_IntAP = 8,
4444
PT_IntAPS = 9,
4545
PT_Bool = 10,
46-
PT_Float = 11,
47-
PT_Ptr = 12,
48-
PT_FnPtr = 13,
49-
PT_MemberPtr = 14,
50-
PT_FixedPoint = 15,
46+
PT_FixedPoint = 11,
47+
PT_Float = 12,
48+
PT_Ptr = 13,
49+
PT_FnPtr = 14,
50+
PT_MemberPtr = 15,
5151
};
5252

5353
inline constexpr bool isPtrType(PrimType T) {
@@ -71,7 +71,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
7171
return OS;
7272
}
7373

74-
constexpr bool isIntegralType(PrimType T) { return T <= PT_Bool; }
74+
constexpr bool isIntegralType(PrimType T) { return T <= PT_FixedPoint; }
7575

7676
/// Mapping from primitive types to their representation.
7777
template <PrimType T> struct PrimConv;

clang/test/AST/ByteCode/fixed-point.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ static_assert((bool)0.0k); // both-error {{static assertion failed}}
77

88
static_assert(1.0k == 1.0k);
99
static_assert(1.0k != 1.0k); // both-error {{failed due to requirement '1.0k != 1.0k'}}
10+
static_assert(-12.0k == -(-(-12.0k)));
11+

0 commit comments

Comments
 (0)