Skip to content

Commit

Permalink
Merged master:faf183874cb6 into amd-gfx:bcf85dfd98b8
Browse files Browse the repository at this point in the history
Local branch amd-gfx bcf85df Merged master:4d83aba4228e into amd-gfx:37f3d80e617b
Remote branch master faf1838 [IndVars] LCSSA Phi users should not prevent widening
  • Loading branch information
Sw authored and Sw committed Nov 27, 2020
2 parents bcf85df + faf1838 commit fcf8045
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 22 deletions.
22 changes: 22 additions & 0 deletions clang-tools-extra/clangd/refactor/Rename.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,28 @@ const NamedDecl *canonicalRenameDecl(const NamedDecl *D) {
if (const auto *Function = dyn_cast<FunctionDecl>(D))
if (const FunctionTemplateDecl *Template = Function->getPrimaryTemplate())
return canonicalRenameDecl(Template);
if (const auto *Field = dyn_cast<FieldDecl>(D)) {
// This is a hacky way to do something like
// CXXMethodDecl::getInstantiatedFromMemberFunction for the field because
// Clang AST does not store relevant information about the field that is
// instantiated.
const auto *FieldParent = dyn_cast<CXXRecordDecl>(Field->getParent());
if (!FieldParent)
return Field->getCanonicalDecl();
FieldParent = FieldParent->getTemplateInstantiationPattern();
// Field is not instantiation.
if (!FieldParent || Field->getParent() == FieldParent)
return Field->getCanonicalDecl();
for (const FieldDecl *Candidate : FieldParent->fields())
if (Field->getDeclName() == Candidate->getDeclName())
return Candidate->getCanonicalDecl();
elog("FieldParent should have field with the same name as Field.");
}
if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember())
VD = OriginalVD;
return VD->getCanonicalDecl();
}
return dyn_cast<NamedDecl>(D->getCanonicalDecl());
}

Expand Down
88 changes: 88 additions & 0 deletions clang-tools-extra/clangd/unittests/RenameTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,94 @@ TEST(RenameTest, WithinFileRename) {
}
)cpp",

// Fields in classes & partial and full specialiations.
R"cpp(
template<typename T>
struct Foo {
T [[Vari^able]] = 42;
};
void foo() {
Foo<int> f;
f.[[Varia^ble]] = 9000;
}
)cpp",
R"cpp(
template<typename T, typename U>
struct Foo {
T Variable[42];
U Another;
void bar() {}
};
template<typename T>
struct Foo<T, bool> {
T [[Var^iable]];
void bar() { ++[[Var^iable]]; }
};
void foo() {
Foo<unsigned, bool> f;
f.[[Var^iable]] = 9000;
}
)cpp",
R"cpp(
template<typename T, typename U>
struct Foo {
T Variable[42];
U Another;
void bar() {}
};
template<typename T>
struct Foo<T, bool> {
T Variable;
void bar() { ++Variable; }
};
template<>
struct Foo<unsigned, bool> {
unsigned [[Var^iable]];
void bar() { ++[[Var^iable]]; }
};
void foo() {
Foo<unsigned, bool> f;
f.[[Var^iable]] = 9000;
}
)cpp",
// Static fields.
R"cpp(
struct Foo {
static int [[Var^iable]];
};
int Foo::[[Var^iable]] = 42;
void foo() {
int LocalInt = Foo::[[Var^iable]];
}
)cpp",
R"cpp(
template<typename T>
struct Foo {
static T [[Var^iable]];
};
template <>
int Foo<int>::[[Var^iable]] = 42;
template <>
bool Foo<bool>::[[Var^iable]] = true;
void foo() {
int LocalInt = Foo<int>::[[Var^iable]];
bool LocalBool = Foo<bool>::[[Var^iable]];
}
)cpp",

// Template parameters.
R"cpp(
template <typename [[^T]]>
Expand Down
35 changes: 30 additions & 5 deletions llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1542,16 +1542,26 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
auto AnotherOpExtKind = ExtKind;

// Check that all uses are either s/zext, or narrow def (in case of we are
// widening the IV increment).
// widening the IV increment), or single-input LCSSA Phis.
SmallVector<Instruction *, 4> ExtUsers;
SmallVector<PHINode *, 4> LCSSAPhiUsers;
for (Use &U : NarrowUse->uses()) {
if (U.getUser() == NarrowDef)
Instruction *User = cast<Instruction>(U.getUser());
if (User == NarrowDef)
continue;
Instruction *User = nullptr;
if (!L->contains(User)) {
auto *LCSSAPhi = cast<PHINode>(User);
// Make sure there is only 1 input, so that we don't have to split
// critical edges.
if (LCSSAPhi->getNumOperands() != 1)
return false;
LCSSAPhiUsers.push_back(LCSSAPhi);
continue;
}
if (ExtKind == SignExtended)
User = dyn_cast<SExtInst>(U.getUser());
User = dyn_cast<SExtInst>(User);
else
User = dyn_cast<ZExtInst>(U.getUser());
User = dyn_cast<ZExtInst>(User);
if (!User || User->getType() != WideType)
return false;
ExtUsers.push_back(User);
Expand Down Expand Up @@ -1630,6 +1640,21 @@ bool WidenIV::widenWithVariantUse(WidenIV::NarrowIVDefUse DU) {
User->replaceAllUsesWith(WideBO);
DeadInsts.emplace_back(User);
}

for (PHINode *User : LCSSAPhiUsers) {
assert(User->getNumOperands() == 1 && "Checked before!");
Builder.SetInsertPoint(User);
auto *WidePN =
Builder.CreatePHI(WideBO->getType(), 1, User->getName() + ".wide");
BasicBlock *LoopExitingBlock = User->getParent()->getSinglePredecessor();
assert(LoopExitingBlock && L->contains(LoopExitingBlock) &&
"Not a LCSSA Phi?");
WidePN->addIncoming(WideBO, LoopExitingBlock);
Builder.SetInsertPoint(User->getParent()->getFirstNonPHI());
auto *TruncPN = Builder.CreateTrunc(WidePN, User->getType());
User->replaceAllUsesWith(TruncPN);
DeadInsts.emplace_back(User);
}
return true;
}

Expand Down
31 changes: 14 additions & 17 deletions llvm/test/Transforms/IndVarSimplify/widen-loop-comp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -697,20 +697,18 @@ define i32 @test14(i32 %start, i32* %p, i32* %q) {
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
; CHECK-NEXT: [[FOO:%.*]] = add i32 [[TMP1]], -1
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[INDEX:%.*]] = zext i32 [[FOO]] to i64
; CHECK-NEXT: [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
; CHECK-NEXT: [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
; CHECK-NEXT: store i32 1, i32* [[STORE_ADDR]], align 4
; CHECK-NEXT: [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
; CHECK-NEXT: [[STOP:%.*]] = load i32, i32* [[Q]], align 4
; CHECK-NEXT: [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
; CHECK: exit:
; CHECK-NEXT: ret i32 -1
; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 -1 to i32
; CHECK-NEXT: ret i32 [[TMP2]]
; CHECK: failure:
; CHECK-NEXT: unreachable
;
Expand Down Expand Up @@ -750,24 +748,23 @@ define i32 @test15(i32 %start, i32* %p, i32* %q) {
; CHECK: loop:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[INDVARS_IV]], 0
; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[INDVARS_IV]] to i32
; CHECK-NEXT: [[FOO:%.*]] = add i32 [[TMP1]], -1
; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[INDEX:%.*]] = zext i32 [[FOO]] to i64
; CHECK-NEXT: [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[INDEX]]
; CHECK-NEXT: [[STORE_ADDR:%.*]] = getelementptr i32, i32* [[P:%.*]], i64 [[TMP1]]
; CHECK-NEXT: store i32 1, i32* [[STORE_ADDR]], align 4
; CHECK-NEXT: [[LOAD_ADDR:%.*]] = getelementptr i32, i32* [[Q:%.*]], i64 [[INDEX]]
; CHECK-NEXT: [[STOP:%.*]] = load i32, i32* [[Q]], align 4
; CHECK-NEXT: [[STOP:%.*]] = load i32, i32* [[Q:%.*]], align 4
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp eq i32 [[STOP]], 0
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[FAILURE:%.*]]
; CHECK: exit:
; CHECK-NEXT: call void @use(i32 -1)
; CHECK-NEXT: ret i32 -1
; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 -1 to i32
; CHECK-NEXT: call void @use(i32 [[TMP2]])
; CHECK-NEXT: ret i32 [[TMP2]]
; CHECK: failure:
; CHECK-NEXT: [[FOO_LCSSA1:%.*]] = phi i32 [ [[FOO]], [[BACKEDGE]] ]
; CHECK-NEXT: call void @use(i32 [[FOO_LCSSA1]])
; CHECK-NEXT: [[FOO_LCSSA1_WIDE:%.*]] = phi i64 [ [[TMP1]], [[BACKEDGE]] ]
; CHECK-NEXT: [[TMP3:%.*]] = trunc i64 [[FOO_LCSSA1_WIDE]] to i32
; CHECK-NEXT: call void @use(i32 [[TMP3]])
; CHECK-NEXT: unreachable
;
entry:
Expand Down

0 comments on commit fcf8045

Please sign in to comment.