forked from OSchip/llvm-project
Revert r275678, "Revert "Revert r275027 - Let FuncAttrs infer the 'returned' argument attribute""
This reverts also r275029, "Update Clang tests after adding inference for the returned argument attribute" It broke LTO build. Seems miscompilation. llvm-svn: 275756
This commit is contained in:
parent
fb946da259
commit
966bde50c3
|
@ -9,5 +9,5 @@ v4sf foo (struct s a) {
|
|||
return a.v;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define <4 x float> @foo(<4 x float> inreg returned %a.coerce)
|
||||
// CHECK-LABEL: define <4 x float> @foo(<4 x float> inreg %a.coerce)
|
||||
// CHECK: ret <4 x float> %a.coerce
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
struct one_field { double d; };
|
||||
test(one_field);
|
||||
// CHECK: define double @_Z7forward9one_field(double returned %{{.*}})
|
||||
// CHECK: define double @_Z7forward9one_field(double %{{.*}})
|
||||
//
|
||||
// CHECK: define void @_Z14test_one_fieldv()
|
||||
// CHECK: %[[call:.*]] = tail call double @_Z13def_one_fieldv()
|
||||
|
@ -89,7 +89,7 @@ struct one_bitfield {
|
|||
int d:3;
|
||||
};
|
||||
test(one_bitfield);
|
||||
// CHECK: define i32 @_Z7forward12one_bitfield(i32 returned %{{.*}})
|
||||
// CHECK: define i32 @_Z7forward12one_bitfield(i32 %{{.*}})
|
||||
//
|
||||
// CHECK: define void @_Z17test_one_bitfieldv()
|
||||
// CHECK: %[[call:.*]] = tail call i32 @_Z16def_one_bitfieldv()
|
||||
|
|
|
@ -51,7 +51,7 @@ int f6(char4 x) {
|
|||
return __builtin_astype(x, int);
|
||||
}
|
||||
|
||||
//CHECK: define spir_func <3 x i8> @f7(<3 x i8> returned %[[x:.*]])
|
||||
//CHECK: define spir_func <3 x i8> @f7(<3 x i8> %[[x:.*]])
|
||||
//CHECK-NOT: bitcast
|
||||
//CHECK-NOT: shufflevector
|
||||
//CHECK: ret <3 x i8> %[[x]]
|
||||
|
|
|
@ -42,7 +42,6 @@ using namespace llvm;
|
|||
STATISTIC(NumReadNone, "Number of functions marked readnone");
|
||||
STATISTIC(NumReadOnly, "Number of functions marked readonly");
|
||||
STATISTIC(NumNoCapture, "Number of arguments marked nocapture");
|
||||
STATISTIC(NumReturned, "Number of arguments marked returned");
|
||||
STATISTIC(NumReadNoneArg, "Number of arguments marked readnone");
|
||||
STATISTIC(NumReadOnlyArg, "Number of arguments marked readonly");
|
||||
STATISTIC(NumNoAlias, "Number of function returns marked noalias");
|
||||
|
@ -484,53 +483,6 @@ determinePointerReadAttrs(Argument *A,
|
|||
return IsRead ? Attribute::ReadOnly : Attribute::ReadNone;
|
||||
}
|
||||
|
||||
/// Deduce returned attributes for the SCC.
|
||||
static bool addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes) {
|
||||
bool Changed = false;
|
||||
|
||||
AttrBuilder B;
|
||||
B.addAttribute(Attribute::Returned);
|
||||
|
||||
// Check each function in turn, determining if an argument is always returned.
|
||||
for (Function *F : SCCNodes) {
|
||||
// We can infer and propagate function attributes only when we know that the
|
||||
// definition we'll get at link time is *exactly* the definition we see now.
|
||||
// For more details, see GlobalValue::mayBeDerefined.
|
||||
if (!F->hasExactDefinition())
|
||||
continue;
|
||||
|
||||
if (F->getReturnType()->isVoidTy())
|
||||
continue;
|
||||
|
||||
auto FindRetArg = [&]() -> Value * {
|
||||
Value *RetArg = nullptr;
|
||||
for (BasicBlock &BB : *F)
|
||||
if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator())) {
|
||||
// Note that stripPointerCasts should look through functions with
|
||||
// returned arguments.
|
||||
Value *RetVal = Ret->getReturnValue()->stripPointerCasts();
|
||||
if (RetVal->getType() == F->getReturnType() && isa<Argument>(RetVal)) {
|
||||
if (!RetArg)
|
||||
RetArg = RetVal;
|
||||
else if (RetArg != RetVal)
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return RetArg;
|
||||
};
|
||||
|
||||
if (Value *RetArg = FindRetArg()) {
|
||||
auto *A = cast<Argument>(RetArg);
|
||||
A->addAttr(AttributeSet::get(F->getContext(), A->getArgNo() + 1, B));
|
||||
++NumReturned;
|
||||
Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
||||
/// Deduce nocapture attributes for the SCC.
|
||||
static bool addArgumentAttrs(const SCCNodeSet &SCCNodes) {
|
||||
bool Changed = false;
|
||||
|
@ -1072,7 +1024,6 @@ PreservedAnalyses PostOrderFunctionAttrsPass::run(LazyCallGraph::SCC &C,
|
|||
}
|
||||
|
||||
bool Changed = false;
|
||||
Changed |= addArgumentReturnedAttrs(SCCNodes);
|
||||
Changed |= addReadAttrs(SCCNodes, AARGetter);
|
||||
Changed |= addArgumentAttrs(SCCNodes);
|
||||
|
||||
|
@ -1138,7 +1089,6 @@ static bool runImpl(CallGraphSCC &SCC, AARGetterT AARGetter) {
|
|||
SCCNodes.insert(F);
|
||||
}
|
||||
|
||||
Changed |= addArgumentReturnedAttrs(SCCNodes);
|
||||
Changed |= addReadAttrs(SCCNodes, AARGetter);
|
||||
Changed |= addArgumentAttrs(SCCNodes);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ define i32* @b(i32 *%q) {
|
|||
ret i32* %tmp
|
||||
}
|
||||
|
||||
; CHECK: define i32* @c(i32* readnone returned %r)
|
||||
; CHECK: define i32* @c(i32* readnone %r)
|
||||
@g = global i32 0
|
||||
define i32* @c(i32 *%r) {
|
||||
%a = icmp eq i32* %r, null
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
; RUN: opt < %s -functionattrs -S | FileCheck %s
|
||||
@g = global i32* null ; <i32**> [#uses=1]
|
||||
|
||||
; CHECK: define i32* @c1(i32* readnone returned %q)
|
||||
; CHECK: define i32* @c1(i32* readnone %q)
|
||||
define i32* @c1(i32* %q) {
|
||||
ret i32* %q
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ define void @test1_1(i8* %x1_1, i8* %y1_1) {
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* returned %y1_2)
|
||||
; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* %y1_2)
|
||||
define i8* @test1_2(i8* %x1_2, i8* %y1_2) {
|
||||
call void @test1_1(i8* %x1_2, i8* %y1_2)
|
||||
store i32* null, i32** @g
|
||||
|
@ -168,7 +168,7 @@ define void @test4_1(i8* %x4_1) {
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned %y4_2, i8* nocapture readnone %z4_2)
|
||||
; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone %y4_2, i8* nocapture readnone %z4_2)
|
||||
define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
|
||||
call void @test4_1(i8* null)
|
||||
store i32* null, i32** @g
|
||||
|
|
|
@ -11,7 +11,7 @@ define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) {
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define i8* @test2(i8* readnone returned %p)
|
||||
; CHECK: define i8* @test2(i8* readnone %p)
|
||||
define i8* @test2(i8* %p) {
|
||||
store i32 0, i32* @x
|
||||
ret i8* %p
|
||||
|
@ -53,7 +53,7 @@ define void @test7_1(i32* inalloca %a) {
|
|||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define i32* @test8_1(i32* readnone returned %p)
|
||||
; CHECK: define i32* @test8_1(i32* readnone %p)
|
||||
define i32* @test8_1(i32* %p) {
|
||||
entry:
|
||||
ret i32* %p
|
||||
|
|
Loading…
Reference in New Issue