1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[IPO/LowerTypesTest] Skip blockaddress(es) when replacing uses.

Blockaddresses refer to the function itself, therefore replacing them
would cause an assertion in doRAUW.

Fixes https://bugs.llvm.org/show_bug.cgi?id=35201

This was found when trying CFI on a proprietary kernel by Dmitry Mikulin.

Differential Revision:  https://reviews.llvm.org/D39695

llvm-svn: 317527
This commit is contained in:
Davide Italiano 2017-11-07 00:09:25 +00:00
parent e070357335
commit 42befee304
4 changed files with 56 additions and 1 deletions

View File

@ -299,6 +299,12 @@ public:
/// values or constant users.
void replaceUsesOutsideBlock(Value *V, BasicBlock *BB);
/// replaceUsesExceptBlockAddr - Go through the uses list for this definition
/// and make each use point to "V" instead of "this" when the use is outside
/// the block. 'This's use list is expected to have at least one element.
/// Unlike replaceAllUsesWith this function skips blockaddr uses.
void replaceUsesExceptBlockAddr(Value *New);
//----------------------------------------------------------------------
// Methods for handling the chain of uses of this Value.
//

View File

@ -454,6 +454,28 @@ void Value::replaceUsesOutsideBlock(Value *New, BasicBlock *BB) {
}
}
void Value::replaceUsesExceptBlockAddr(Value *New) {
use_iterator UI = use_begin(), E = use_end();
for (; UI != E;) {
Use &U = *UI;
++UI;
if (isa<BlockAddress>(U.getUser()))
continue;
// Must handle Constants specially, we cannot call replaceUsesOfWith on a
// constant because they are uniqued.
if (auto *C = dyn_cast<Constant>(U.getUser())) {
if (!isa<GlobalValue>(C)) {
C->handleOperandChange(this, New);
continue;
}
}
U.set(New);
}
}
namespace {
// Various metrics for how much to strip off of pointers.
enum PointerStripKind {

View File

@ -1401,7 +1401,7 @@ void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
FAlias->takeName(F);
if (FAlias->hasName())
F->setName(FAlias->getName() + ".cfi");
F->replaceAllUsesWith(FAlias);
F->replaceUsesExceptBlockAddr(FAlias);
}
if (!F->isDeclarationForLinker())
F->setLinkage(GlobalValue::InternalLinkage);

View File

@ -0,0 +1,27 @@
; RUN: opt -S %s -lowertypetests | FileCheck %s
; CHECK: define internal i8* @f2.cfi() !type !0 {
; CHECK-NEXT: br label %b
; CHECK: b:
; CHECK-NEXT: ret i8* blockaddress(@f2.cfi, %b)
; CHECK-NEXT: }
target triple = "x86_64-unknown-linux"
define void @f1() {
entry:
%0 = call i1 @llvm.type.test(i8* bitcast (i8* ()* @f2 to i8*), metadata !"_ZTSFvP3bioE")
ret void
}
declare i1 @llvm.type.test(i8*, metadata)
define i8* @f2() !type !5 {
br label %b
b:
ret i8* blockaddress(@f2, %b)
}
!5 = !{i64 0, !"_ZTSFvP3bioE"}