Skip to content

Commit cb26d6a

Browse files
committed
[clang] Handle fp options in __builtin_convertvector
This patch allows using fpfeatures pragmas with __builtin_convertvector: - added TrailingObjects with FPOptionsOverride and methods for handling it to ConvertVectorExpr - added support for codegen, node dumping, and serialization of fpfeatures contained in ConvertVectorExpr
1 parent 557c8bf commit cb26d6a

File tree

12 files changed

+163
-12
lines changed

12 files changed

+163
-12
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4579,25 +4579,97 @@ class ShuffleVectorExpr : public Expr {
45794579
/// ConvertVectorExpr - Clang builtin function __builtin_convertvector
45804580
/// This AST node provides support for converting a vector type to another
45814581
/// vector type of the same arity.
4582-
class ConvertVectorExpr : public Expr {
4582+
class ConvertVectorExpr final
4583+
: public Expr,
4584+
private llvm::TrailingObjects<ConvertVectorExpr, FPOptionsOverride> {
45834585
private:
45844586
Stmt *SrcExpr;
45854587
TypeSourceInfo *TInfo;
45864588
SourceLocation BuiltinLoc, RParenLoc;
45874589

4590+
friend TrailingObjects;
45884591
friend class ASTReader;
45894592
friend class ASTStmtReader;
4590-
explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {}
4593+
explicit ConvertVectorExpr(bool HasFPFeatures, EmptyShell Empty)
4594+
: Expr(ConvertVectorExprClass, Empty) {
4595+
ConvertVectorExprBits.HasFPFeatures = HasFPFeatures;
4596+
}
45914597

4592-
public:
45934598
ConvertVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType,
45944599
ExprValueKind VK, ExprObjectKind OK,
4595-
SourceLocation BuiltinLoc, SourceLocation RParenLoc)
4600+
SourceLocation BuiltinLoc, SourceLocation RParenLoc,
4601+
FPOptionsOverride FPFeatures)
45964602
: Expr(ConvertVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr),
45974603
TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {
4604+
ConvertVectorExprBits.HasFPFeatures = FPFeatures.requiresTrailingStorage();
4605+
if (hasStoredFPFeatures())
4606+
setStoredFPFeatures(FPFeatures);
45984607
setDependence(computeDependence(this));
45994608
}
46004609

4610+
size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const {
4611+
return ConvertVectorExprBits.HasFPFeatures ? 1 : 0;
4612+
}
4613+
4614+
FPOptionsOverride &getTrailingFPFeatures() {
4615+
assert(ConvertVectorExprBits.HasFPFeatures);
4616+
return *getTrailingObjects<FPOptionsOverride>();
4617+
}
4618+
4619+
const FPOptionsOverride &getTrailingFPFeatures() const {
4620+
assert(ConvertVectorExprBits.HasFPFeatures);
4621+
return *getTrailingObjects<FPOptionsOverride>();
4622+
}
4623+
4624+
public:
4625+
static ConvertVectorExpr *CreateEmpty(const ASTContext &C,
4626+
bool hasFPFeatures);
4627+
4628+
static ConvertVectorExpr *Create(const ASTContext &C, Expr *SrcExpr,
4629+
TypeSourceInfo *TI, QualType DstType,
4630+
ExprValueKind VK, ExprObjectKind OK,
4631+
SourceLocation BuiltinLoc,
4632+
SourceLocation RParenLoc,
4633+
FPOptionsOverride FPFeatures);
4634+
4635+
/// Get the FP contractibility status of this operator. Only meaningful for
4636+
/// operations on floating point types.
4637+
bool isFPContractableWithinStatement(const LangOptions &LO) const {
4638+
return getFPFeaturesInEffect(LO).allowFPContractWithinStatement();
4639+
}
4640+
4641+
/// Is FPFeatures in Trailing Storage?
4642+
bool hasStoredFPFeatures() const {
4643+
return ConvertVectorExprBits.HasFPFeatures;
4644+
}
4645+
4646+
/// Get FPFeatures from trailing storage.
4647+
FPOptionsOverride getStoredFPFeatures() const {
4648+
return getTrailingFPFeatures();
4649+
}
4650+
4651+
/// Get the store FPOptionsOverride or default if not stored.
4652+
FPOptionsOverride getStoredFPFeaturesOrDefault() const {
4653+
return hasStoredFPFeatures() ? getStoredFPFeatures() : FPOptionsOverride();
4654+
}
4655+
4656+
/// Set FPFeatures in trailing storage, used by Serialization & ASTImporter.
4657+
void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; }
4658+
4659+
/// Get the FP features status of this operator. Only meaningful for
4660+
/// operations on floating point types.
4661+
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const {
4662+
if (ConvertVectorExprBits.HasFPFeatures)
4663+
return getStoredFPFeatures().applyOverrides(LO);
4664+
return FPOptions::defaultWithoutTrailingStorage(LO);
4665+
}
4666+
4667+
FPOptionsOverride getFPOptionsOverride() const {
4668+
if (ConvertVectorExprBits.HasFPFeatures)
4669+
return getStoredFPFeatures();
4670+
return FPOptionsOverride();
4671+
}
4672+
46014673
/// getSrcExpr - Return the Expr to be converted.
46024674
Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); }
46034675

clang/include/clang/AST/Stmt.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,6 +1215,20 @@ class alignas(void *) Stmt {
12151215
SourceLocation Loc;
12161216
};
12171217

1218+
class ConvertVectorExprBitfields {
1219+
friend class ConvertVectorExpr;
1220+
1221+
LLVM_PREFERRED_TYPE(ExprBitfields)
1222+
unsigned : NumExprBits;
1223+
1224+
//
1225+
/// This is only meaningful for operations on floating point
1226+
/// types when additional values need to be in trailing storage.
1227+
/// It is 0 otherwise.
1228+
LLVM_PREFERRED_TYPE(bool)
1229+
unsigned HasFPFeatures : 1;
1230+
};
1231+
12181232
union {
12191233
// Same order as in StmtNodes.td.
12201234
// Statements
@@ -1293,6 +1307,7 @@ class alignas(void *) Stmt {
12931307

12941308
// Clang Extensions
12951309
OpaqueValueExprBitfields OpaqueValueExprBits;
1310+
ConvertVectorExprBitfields ConvertVectorExprBits;
12961311
};
12971312

12981313
public:

clang/include/clang/AST/TextNodeDumper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ class TextNodeDumper
424424
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
425425
void VisitEmbedExpr(const EmbedExpr *S);
426426
void VisitAtomicExpr(const AtomicExpr *AE);
427+
void VisitConvertVectorExpr(const ConvertVectorExpr *S);
427428
};
428429

429430
} // namespace clang

clang/lib/AST/ASTImporter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7386,9 +7386,10 @@ ExpectedStmt ASTNodeImporter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
73867386
if (Err)
73877387
return std::move(Err);
73887388

7389-
return new (Importer.getToContext())
7390-
ConvertVectorExpr(ToSrcExpr, ToTSI, ToType, E->getValueKind(),
7391-
E->getObjectKind(), ToBuiltinLoc, ToRParenLoc);
7389+
return ConvertVectorExpr::Create(
7390+
Importer.getToContext(), ToSrcExpr, ToTSI, ToType, E->getValueKind(),
7391+
E->getObjectKind(), ToBuiltinLoc, ToRParenLoc,
7392+
E->getStoredFPFeaturesOrDefault());
73927393
}
73937394

73947395
ExpectedStmt ASTNodeImporter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {

clang/lib/AST/Expr.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3899,6 +3899,8 @@ FPOptions Expr::getFPFeaturesInEffect(const LangOptions &LO) const {
38993899
return BO->getFPFeaturesInEffect(LO);
39003900
if (auto Cast = dyn_cast<CastExpr>(this))
39013901
return Cast->getFPFeaturesInEffect(LO);
3902+
if (auto ConvertVector = dyn_cast<ConvertVectorExpr>(this))
3903+
return ConvertVector->getFPFeaturesInEffect(LO);
39023904
return FPOptions::defaultWithoutTrailingStorage(LO);
39033905
}
39043906

@@ -5439,3 +5441,21 @@ OpenACCAsteriskSizeExpr *
54395441
OpenACCAsteriskSizeExpr::CreateEmpty(const ASTContext &C) {
54405442
return new (C) OpenACCAsteriskSizeExpr({}, C.IntTy);
54415443
}
5444+
5445+
ConvertVectorExpr *ConvertVectorExpr::CreateEmpty(const ASTContext &C,
5446+
bool hasFPFeatures) {
5447+
void *Mem = C.Allocate(totalSizeToAlloc<FPOptionsOverride>(hasFPFeatures),
5448+
alignof(ConvertVectorExpr));
5449+
return new (Mem) ConvertVectorExpr(hasFPFeatures, EmptyShell());
5450+
}
5451+
5452+
ConvertVectorExpr *ConvertVectorExpr::Create(
5453+
const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType,
5454+
ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc,
5455+
SourceLocation RParenLoc, FPOptionsOverride FPFeatures) {
5456+
bool HasFPFeatures = FPFeatures.requiresTrailingStorage();
5457+
unsigned Size = totalSizeToAlloc<FPOptionsOverride>(HasFPFeatures);
5458+
void *Mem = C.Allocate(Size, alignof(ConvertVectorExpr));
5459+
return new (Mem) ConvertVectorExpr(SrcExpr, TI, DstType, VK, OK, BuiltinLoc,
5460+
RParenLoc, FPFeatures);
5461+
}

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,3 +3055,9 @@ void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) {
30553055
void TextNodeDumper::VisitAtomicExpr(const AtomicExpr *AE) {
30563056
OS << ' ' << AE->getOpAsString();
30573057
}
3058+
3059+
void TextNodeDumper::VisitConvertVectorExpr(const ConvertVectorExpr *S) {
3060+
VisitStmt(S);
3061+
if (S->hasStoredFPFeatures())
3062+
printFPOptions(S->getStoredFPFeatures());
3063+
}

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,7 @@ Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
19491949

19501950
llvm::Value *Zero = llvm::Constant::getNullValue(SrcTy);
19511951
if (SrcEltTy->isFloatingPointTy()) {
1952+
CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
19521953
return Builder.CreateFCmpUNE(Src, Zero, "tobool");
19531954
} else {
19541955
return Builder.CreateICmpNE(Src, Zero, "tobool");
@@ -1975,6 +1976,7 @@ Value *ScalarExprEmitter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
19751976
} else {
19761977
assert(SrcEltTy->isFloatingPointTy() && DstEltTy->isFloatingPointTy() &&
19771978
"Unknown real conversion");
1979+
CodeGenFunction::CGFPOptionsRAII FPOptions(CGF, E);
19781980
if (DstEltTy->getTypeID() < SrcEltTy->getTypeID())
19791981
Res = Builder.CreateFPTrunc(Src, DstTy, "conv");
19801982
else

clang/lib/Sema/SemaChecking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5261,8 +5261,8 @@ ExprResult Sema::ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
52615261
<< E->getSourceRange());
52625262
}
52635263

5264-
return new (Context) class ConvertVectorExpr(E, TInfo, DstTy, VK, OK,
5265-
BuiltinLoc, RParenLoc);
5264+
return ConvertVectorExpr::Create(Context, E, TInfo, DstTy, VK, OK, BuiltinLoc,
5265+
RParenLoc, CurFPFeatureOverrides());
52665266
}
52675267

52685268
bool Sema::BuiltinPrefetch(CallExpr *TheCall) {

clang/lib/Serialization/ASTReaderStmt.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,10 +1387,15 @@ void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
13871387

13881388
void ASTStmtReader::VisitConvertVectorExpr(ConvertVectorExpr *E) {
13891389
VisitExpr(E);
1390+
bool HasFPFeatures = CurrentUnpackingBits->getNextBit();
1391+
assert(HasFPFeatures == E->hasStoredFPFeatures());
13901392
E->BuiltinLoc = readSourceLocation();
13911393
E->RParenLoc = readSourceLocation();
13921394
E->TInfo = readTypeSourceInfo();
13931395
E->SrcExpr = Record.readSubExpr();
1396+
if (HasFPFeatures)
1397+
E->setStoredFPFeatures(
1398+
FPOptionsOverride::getFromOpaqueInt(Record.readInt()));
13941399
}
13951400

13961401
void ASTStmtReader::VisitBlockExpr(BlockExpr *E) {
@@ -3391,9 +3396,13 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
33913396
S = new (Context) ShuffleVectorExpr(Empty);
33923397
break;
33933398

3394-
case EXPR_CONVERT_VECTOR:
3395-
S = new (Context) ConvertVectorExpr(Empty);
3399+
case EXPR_CONVERT_VECTOR: {
3400+
BitsUnpacker ConvertVectorExprBits(Record[ASTStmtReader::NumStmtFields]);
3401+
ConvertVectorExprBits.advance(ASTStmtReader::NumExprBits);
3402+
bool HasFPFeatures = ConvertVectorExprBits.getNextBit();
3403+
S = ConvertVectorExpr::CreateEmpty(Context, HasFPFeatures);
33963404
break;
3405+
}
33973406

33983407
case EXPR_BLOCK:
33993408
S = new (Context) BlockExpr(Empty);

clang/lib/Serialization/ASTWriterStmt.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,11 +1335,15 @@ void ASTStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
13351335

13361336
void ASTStmtWriter::VisitConvertVectorExpr(ConvertVectorExpr *E) {
13371337
VisitExpr(E);
1338+
bool HasFPFeatures = E->hasStoredFPFeatures();
1339+
CurrentPackingBits.addBit(HasFPFeatures);
13381340
Record.AddSourceLocation(E->getBuiltinLoc());
13391341
Record.AddSourceLocation(E->getRParenLoc());
13401342
Record.AddTypeSourceInfo(E->getTypeSourceInfo());
13411343
Record.AddStmt(E->getSrcExpr());
13421344
Code = serialization::EXPR_CONVERT_VECTOR;
1345+
if (HasFPFeatures)
1346+
Record.push_back(E->getStoredFPFeatures().getAsOpaqueInt());
13431347
}
13441348

13451349
void ASTStmtWriter::VisitBlockExpr(BlockExpr *E) {

clang/test/AST/ast-dump-fpfeatures.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,16 @@ __attribute__((optnone)) T func_22(T x, T y) {
248248

249249
float func_23(float x, float y) {
250250
return func_22(x, y);
251-
}
251+
}
252+
253+
// CHECK-LABEL: FunctionDecl {{.*}} func_24 'vector2float (vector2double)'
254+
// CHECK: CompoundStmt {{.*}} FPContractMode=2 ConstRoundingMode=towardzero
255+
// CHECK: ReturnStmt
256+
// CHECK: ConvertVectorExpr {{.*}} FPContractMode=2 ConstRoundingMode=towardzero
257+
258+
typedef double vector2double __attribute__((__vector_size__(16)));
259+
typedef float vector2float __attribute__((__vector_size__(8)));
260+
#pragma STDC FENV_ROUND FE_TOWARDZERO
261+
vector2float func_24(vector2double x) {
262+
return __builtin_convertvector(x, vector2float);
263+
}

clang/test/CodeGen/pragma-fenv_access.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,12 @@ float func_20(float x, float y) {
242242
// CHECK-LABEL: @func_20
243243
// STRICT: call float @llvm.experimental.constrained.fadd.f32(float {{.*}}, float {{.*}}, metadata !"round.tonearest", metadata !"fpexcept.strict")
244244
// DEFAULT: fadd float
245+
246+
typedef double vector4double __attribute__((__vector_size__(32)));
247+
typedef float vector4float __attribute__((__vector_size__(16)));
248+
vector4float func_21(vector4double x) {
249+
#pragma STDC FENV_ROUND FE_UPWARD
250+
return __builtin_convertvector(x, vector4float);
251+
}
252+
// CHECK-LABEL: @func_21
253+
// STRICT: call <4 x float> @llvm.experimental.constrained.fptrunc.v4f32.v4f64(<4 x double> {{.*}}, metadata !"round.upward", metadata !"fpexcept.strict")

0 commit comments

Comments
 (0)