Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

redundant load not removed #10664

Open
llvmbot opened this issue Jul 7, 2011 · 9 comments
Open

redundant load not removed #10664

llvmbot opened this issue Jul 7, 2011 · 9 comments
Labels
bugzilla Issues migrated from bugzilla llvm:optimizations

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 7, 2011

Bugzilla Link 10292
Version trunk
OS All
Reporter LLVM Bugzilla Contributor
CC @fhahn,@sunfishcode

Extended Description

In the following example, tmp5 could be removed.

%zed = type { i8* }

define void @​test(%zed** %bar) {
%tmp1 = alloca i8, align 8
%tmp2 = load %zed** %bar, align 8
%tmp3 = getelementptr inbounds %zed* %tmp2, i64 0, i32 0
%tmp4 = load i8** %tmp3, align 8
call void @​llvm.memcpy.p0i8.p0i8.i64(i8* %tmp1, i8* %tmp4, i64 24, i32 8, i1 false)
%tmp5 = load i8** %tmp3, align 8
call void @​foobar(i8* %tmp1)
call void @​foobar(i8* %tmp5)
ret void
}

declare void @​foobar(i8*)

declare void @​llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 8, 2011

We can handle a slightly simpler case:

define void @​test2(%zed* nocapture %bar) {
%tmp1 = alloca i8, align 8
%tmp3 = getelementptr inbounds %zed* %bar, i64 0, i32 0
%tmp4 = load i8** %tmp3, align 8
call void @​llvm.memcpy.p0i8.p0i8.i64(i8* %tmp1, i8* %tmp4, i64 24, i32 8, i1 false)
%tmp5 = load i8** %tmp3, align 8
call void @​foobar(i8* %tmp1)
call void @​foobar(i8* %tmp5)
ret void
}

What makes us handle it is the logic:

// Arguments can't alias with local allocations or noalias calls
// in the same function.
if (((isa<Argument>(O1) && (isa<AllocaInst>(O2) || isNoAliasCall(O2))) ||
     (isa<Argument>(O2) && (isa<AllocaInst>(O1) || isNoAliasCall(O1)))))
  return NoAlias;

In the original testcase it fails because O2 is

%tmp2 = load %zed** %bar, align 8

and %bar is the argument.

Can BasicAliasAnalysis use memdep to find that no store could have set the result of that load to be a local (alloca or no alias call) value?

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 8, 2011

Just some notes:

*) For allocas (but not non alias calls), we just need to consider the entry bb if we don't care about dynamic allocas (which we probably don't)

*) On this case at least, the check can be as simple as: before the first instruction in the entry bb that writes to memory.

I am currently reducing the original c++ testcase too to see if these rules still apply and if there is anything that clang could do to make llvm's task easier.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 8, 2011

The C++ testcase:

class FrameRegs {
int *a;
int *b;
};
struct StackSegment {
FrameRegs *regs_;
};
struct ContextStack {
StackSegment *seg_;
};
struct InterpExitGuard {
FrameRegs *prevContextRegs;
InterpExitGuard(StackSegment *seg_, FrameRegs *regs) {
prevContextRegs = seg_->regs_;
seg_->regs_ = regs;
*prevContextRegs = *regs;
}
};
void Interpret(ContextStack *stack) {
FrameRegs regs = *stack->seg_->regs_;
InterpExitGuard interpGuard(stack->seg_, &regs);
}

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 8, 2011

The code clang generates looks pretty reasonable, the two loads are just the two stack->seg_.

My current idea is to add pointsTNonLocalMemory to the alias analysis interface and add a really simple implementation to the basic alias analysis.

Sounds reasonable?

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 10, 2011

proposed patch
I will give the tree some time to stabilize after the type system rewrite so that I can test this better.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 10, 2011

new patch
I had to make the check a bit more aggressive for it to have an effect on the
original jsinterp.ii. With this patch we successfully avoid a load, but the
stack usage is still higher than gcc's :-(

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jul 21, 2011

fixed patch
with only the relevant chages

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 15, 2013

rdar://13017143

@fhahn
Copy link
Contributor

fhahn commented Aug 18, 2020

Still an issue: https://godbolt.org/z/4v84v6

I think we should be able to weed out such loads at the end of MemorySSA-backed DSE.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla llvm:optimizations
Projects
None yet
Development

No branches or pull requests

3 participants