Skip to content

Commit 90cdc03

Browse files
authored
[IR] Fix undiagnosed cases of structs containing scalable vectors (#113455)
Type::isScalableTy and StructType::containsScalableVectorType failed to detect some cases of structs containing scalable vectors because containsScalableVectorType did not call back into isScalableTy to check the element types. Fix this, which requires sharing the same Visited set in both functions. Also change the external API so that callers are never required to pass in a Visited set, and normalize the naming to isScalableTy.
1 parent 2c0b348 commit 90cdc03

File tree

7 files changed

+32
-23
lines changed

7 files changed

+32
-23
lines changed

llvm/include/llvm/IR/DerivedTypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,8 @@ class StructType : public Type {
290290
bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const;
291291

292292
/// Returns true if this struct contains a scalable vector.
293-
bool
294-
containsScalableVectorType(SmallPtrSetImpl<Type *> *Visited = nullptr) const;
293+
bool isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const;
294+
using Type::isScalableTy;
295295

296296
/// Returns true if this struct contains homogeneous scalable vector types.
297297
/// Note that the definition of homogeneous scalable vector type is not

llvm/include/llvm/IR/Type.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ class Type {
206206
bool isScalableTargetExtTy() const;
207207

208208
/// Return true if this is a type whose size is a known multiple of vscale.
209+
bool isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const;
209210
bool isScalableTy() const;
210211

211212
/// Return true if this is a FP type or a vector of FP.

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8525,7 +8525,7 @@ int LLParser::parseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
85258525
return error(Loc, "base element of getelementptr must be sized");
85268526

85278527
auto *STy = dyn_cast<StructType>(Ty);
8528-
if (STy && STy->containsScalableVectorType())
8528+
if (STy && STy->isScalableTy())
85298529
return error(Loc, "getelementptr cannot target structure that contains "
85308530
"scalable vector type");
85318531

llvm/lib/IR/Type.cpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,19 @@ bool Type::isIntegerTy(unsigned Bitwidth) const {
5858
return isIntegerTy() && cast<IntegerType>(this)->getBitWidth() == Bitwidth;
5959
}
6060

61-
bool Type::isScalableTy() const {
61+
bool Type::isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const {
6262
if (const auto *ATy = dyn_cast<ArrayType>(this))
63-
return ATy->getElementType()->isScalableTy();
64-
if (const auto *STy = dyn_cast<StructType>(this)) {
65-
SmallPtrSet<Type *, 4> Visited;
66-
return STy->containsScalableVectorType(&Visited);
67-
}
63+
return ATy->getElementType()->isScalableTy(Visited);
64+
if (const auto *STy = dyn_cast<StructType>(this))
65+
return STy->isScalableTy(Visited);
6866
return getTypeID() == ScalableVectorTyID || isScalableTargetExtTy();
6967
}
7068

69+
bool Type::isScalableTy() const {
70+
SmallPtrSet<const Type *, 4> Visited;
71+
return isScalableTy(Visited);
72+
}
73+
7174
const fltSemantics &Type::getFltSemantics() const {
7275
switch (getTypeID()) {
7376
case HalfTyID: return APFloat::IEEEhalf();
@@ -394,30 +397,22 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
394397
return ST;
395398
}
396399

397-
bool StructType::containsScalableVectorType(
398-
SmallPtrSetImpl<Type *> *Visited) const {
400+
bool StructType::isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const {
399401
if ((getSubclassData() & SCDB_ContainsScalableVector) != 0)
400402
return true;
401403

402404
if ((getSubclassData() & SCDB_NotContainsScalableVector) != 0)
403405
return false;
404406

405-
if (Visited && !Visited->insert(const_cast<StructType *>(this)).second)
407+
if (!Visited.insert(this).second)
406408
return false;
407409

408410
for (Type *Ty : elements()) {
409-
if (isa<ScalableVectorType>(Ty)) {
411+
if (Ty->isScalableTy(Visited)) {
410412
const_cast<StructType *>(this)->setSubclassData(
411413
getSubclassData() | SCDB_ContainsScalableVector);
412414
return true;
413415
}
414-
if (auto *STy = dyn_cast<StructType>(Ty)) {
415-
if (STy->containsScalableVectorType(Visited)) {
416-
const_cast<StructType *>(this)->setSubclassData(
417-
getSubclassData() | SCDB_ContainsScalableVector);
418-
return true;
419-
}
420-
}
421416
}
422417

423418
// For structures that are opaque, return false but do not set the

llvm/lib/IR/Verifier.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4107,8 +4107,7 @@ void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) {
41074107
Check(GEP.getSourceElementType()->isSized(), "GEP into unsized type!", &GEP);
41084108

41094109
if (auto *STy = dyn_cast<StructType>(GEP.getSourceElementType())) {
4110-
SmallPtrSet<Type *, 4> Visited;
4111-
Check(!STy->containsScalableVectorType(&Visited),
4110+
Check(!STy->isScalableTy(),
41124111
"getelementptr cannot target structure that contains scalable vector"
41134112
"type",
41144113
&GEP);

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4087,7 +4087,7 @@ Instruction *InstCombinerImpl::visitExtractValueInst(ExtractValueInst &EV) {
40874087
if (LoadInst *L = dyn_cast<LoadInst>(Agg)) {
40884088
// Bail out if the aggregate contains scalable vector type
40894089
if (auto *STy = dyn_cast<StructType>(Agg->getType());
4090-
STy && STy->containsScalableVectorType())
4090+
STy && STy->isScalableTy())
40914091
return nullptr;
40924092

40934093
// If the (non-volatile) load only has one use, we can rewrite this to a

llvm/test/Verifier/scalable-global-vars.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,17 @@
1515
; CHECK-NEXT: ptr @ScalableVecStructGlobal
1616
@ScalableVecStructGlobal = global { i32, <vscale x 4 x i32> } zeroinitializer
1717

18+
; CHECK-NEXT: Globals cannot contain scalable types
19+
; CHECK-NEXT: ptr @StructTestGlobal
20+
%struct.test = type { <vscale x 1 x double>, <vscale x 1 x double> }
21+
@StructTestGlobal = global %struct.test zeroinitializer
22+
23+
; CHECK-NEXT: Globals cannot contain scalable types
24+
; CHECK-NEXT: ptr @StructArrayTestGlobal
25+
%struct.array.test = type { [2 x <vscale x 1 x double>] }
26+
@StructArrayTestGlobal = global %struct.array.test zeroinitializer
27+
28+
; CHECK-NEXT: Globals cannot contain scalable types
29+
; CHECK-NEXT: ptr @StructTargetTestGlobal
30+
%struct.target.test = type { target("aarch64.svcount"), target("aarch64.svcount") }
31+
@StructTargetTestGlobal = global %struct.target.test zeroinitializer

0 commit comments

Comments
 (0)