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

wrong code (bad esp update) with -enable-llvm on x86 #1770

Closed
llvmbot opened this issue May 7, 2007 · 12 comments
Closed

wrong code (bad esp update) with -enable-llvm on x86 #1770

llvmbot opened this issue May 7, 2007 · 12 comments
Labels
bugzilla Issues migrated from bugzilla

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented May 7, 2007

Bugzilla Link 1398
Resolution FIXED
Resolved on Feb 22, 2010 12:48
Version unspecified
OS Linux
Attachments testcase .ll
Reporter LLVM Bugzilla Contributor
CC @asl

Extended Description

I've been seeing mysterious segfaults when compiling using
-enable-llvm, even though no exceptions are raised. It turns
out to be due to a wrong stack pointer update:

$ llc ol.bc -o no_eh
$ llc ol.bc -enable-eh -o eh
$ diff no_eh eh
...
144c153,155
< addl $12, %esp

  addl $16, %esp

If I change the $16 to $12 in the eh .s, then
the segfault goes away and all is well.

@asl
Copy link
Collaborator

asl commented May 7, 2007

Does code generated with -disable-fp-elim fail too?

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

Yes, it still fails with -disable-fp-elim. In fact
-disable-fp-elim doesn't result in any changes for the
first 500 lines of assembler or so. With or without
-disable-fp-elim, the frame pointer (ebp) is still being
set up at the start of the function and used in a bunch
of places (not everywhere)!

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

The reason -disable-fp-elim has no particular effect is that the function
contains variable sized allocas:
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas
or
// if frame pointer elimination is disabled.

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

From X86RegisterInfo.cpp:956:

    assert(Old->getOpcode() == X86::ADJCALLSTACKUP);
    // factor out the amount the callee already popped.
    uint64_t CalleeAmt = Old->getOperand(1).getImm();
    Amount -= CalleeAmt;

With -enable-eh, CalleeAmt is 0; without it CalleeAmt is 4.
Presumably this is caused somehow by a difference between
invoke and call.

@asl
Copy link
Collaborator

asl commented May 7, 2007

Hrm, this is pretty strange... I'll have a look.

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

It may come from here:

// If the first argument is an sret pointer, remember it.
bool isSRet = NumOps &&
(cast(Op.getOperand(6))->getValue() &
ISD::ParamFlags::StructReturn);

Whether isSRet is true or not results in a 4 byte difference
in the stack popping after a call. It is true the first two
times I get here without -enable-eh, and true then false with
-enable-eh. Of course it is possible that these don't correspond
to the same calls, if the DAG is being visited in a different
order...

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

The invoke which gets the wrong stack pop amount after it, is

invoke void @​ol__normalize_pathname__get_directory.180
( %struct.string___XUP* %tmp59
sret , %struct.FRAME.ol__normalize_pathname* %FRAME.11, i64 %tmp255 )

which is indeed a struct return.

@asl
Copy link
Collaborator

asl commented May 7, 2007

Well, if case of struct return callee should pop hidden pointer from stack. So,
12 is right and 16 is not.

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

Well, if case of struct return callee should pop hidden pointer from stack.
So, 12 is right and 16 is not.

Exactly: with 12 it works, with 16 it dies horribly.

@asl
Copy link
Collaborator

asl commented May 7, 2007

Investigating

@llvmbot
Copy link
Collaborator Author

llvmbot commented May 7, 2007

Solution proposed by aKor on IRC:

(09:32:17 PM) aKor[off-site]: in SelectionDAGLowering::LowerCallTo
(09:32:49 PM) aKor[off-site]: change paramHasAttr(i, ...) to
paramHasAttr(i-OpIdx+1, ...)
(09:33:00 PM) aKor[off-site]: i is operand index
(09:33:03 PM) aKor[off-site]: not parameter
(09:33:09 PM) aKor[off-site]: it's ok for calls
(09:33:11 PM) aKor[off-site]: but not for invokes

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

No branches or pull requests

2 participants