Skip to content
This repository has been archived by the owner on Feb 5, 2019. It is now read-only.

Fixes SjLj preparation step on iOS #12

Closed
wants to merge 4 commits into from

Conversation

vhbit
Copy link

@vhbit vhbit commented Jun 23, 2014

Rebased on current used head.

@vhbit
Copy link
Author

vhbit commented Jun 23, 2014

@alexcrichton PR to LLVM is here: http://reviews.llvm.org/D4256
Let me know if it is possible to merge it into current head and remove later on once it is upstreamed into LLVM as currently Rust doesn't build for iOS and I do not think patching std lib with tons "FIXMEs" is a better way to make it work.

@alexcrichton
Copy link
Member

I'd like to wait for a little bit to see what upstream says.

Cameron Zwarich added 2 commits June 28, 2014 00:19
This pass is not Rust-specific, in that all of its transformations are
intended to be correct for arbitrary LLVM IR, but it targets idioms
found in IR generated by `rustc`, e.g. heavy use of `inbounds` GEPs.
Since the NullCheckElimination pass has a similar intent to the
CorrelatedValuePropagation pass, I decided to run it right after the
both places that the latter runs.
DiamondLovesYou pushed a commit to DiamondLovesYou/llvm that referenced this pull request Jun 29, 2014
The full string used to be "// =rust-lang#12" for example, which looks too
busy.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209443 91177308-0d34-0410-b5e6-96231b3b80d8
Cameron Zwarich and others added 2 commits July 9, 2014 23:49
Teach the NullCheckElimination pass about recurrences involving inbounds
GEPs. This allows the pass to optimize null checks from most uses of
single slice and vector iterators.

This still isn't sufficient to eliminate null checks from uses of
multiple iterators with zip().
This crash was pretty common while compiling Rust for iOS (armv7). Reason -
SjLj preparation step was lowering aggregate arguments as ExtractValue +
InsertValue. ExtractValue has assertion which checks that there is some data in
value, which is not true in case of empty (no fields) structures. Rust uses
them quite extensively so this patch uses a 'select true, %val, undef'
instruction to lower the argument.

Patch by Valerii Hiora.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212922 91177308-0d34-0410-b5e6-96231b3b80d8
@alexcrichton
Copy link
Member

I believe this was covered by #16

alexcrichton pushed a commit that referenced this pull request Aug 4, 2015
No functional change because "lsl #12" is actually encoded as 12, but one less
bug if someone ever decides to change that for the giggles.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243536 91177308-0d34-0410-b5e6-96231b3b80d8
alexcrichton pushed a commit that referenced this pull request Feb 9, 2018
…ddress operands

Currently the assembler would accept, e.g. `ldr r0, [s0, #12]` and similar.
This patch add checks that only general-purpose registers are used in address
operands, shifted registers, and shift amounts.

Differential revision: https://reviews.llvm.org/D39910



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@321866 91177308-0d34-0410-b5e6-96231b3b80d8
alexcrichton pushed a commit that referenced this pull request Aug 2, 2018
This reverts commit r337504 while I investigate a TSan bot failure that
seems related:

http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-autoconf/builds/26526

    #8 0x000055581f2895d8 (/b/sanitizer-x86_64-linux-autoconf/build/tsan_debug_build/bin/clang-7+0x1eb45d8)
    #9 0x000055581f294323 llvm::ConstantAggrKeyType<llvm::ConstantArray>::create(llvm::ArrayType*) const /b/sanitizer-x86_64-linux-autoconf/build/llvm/lib/IR/ConstantsContext.h:409:0
    #10 0x000055581f294323 llvm::ConstantUniqueMap<llvm::ConstantArray>::create(llvm::ArrayType*, llvm::ConstantAggrKeyType<llvm::ConstantArray>, std::pair<unsigned int, std::pair<llvm::ArrayType*, llvm::ConstantAggrKeyType<llvm::ConstantArray> > >&) /b/sanitizer-x86_64-linux-autoconf/build/llvm/lib/IR/ConstantsContext.h:635:0
    #11 0x000055581f294323 llvm::ConstantUniqueMap<llvm::ConstantArray>::getOrCreate(llvm::ArrayType*, llvm::ConstantAggrKeyType<llvm::ConstantArray>) /b/sanitizer-x86_64-linux-autoconf/build/llvm/lib/IR/ConstantsContext.h:654:0
    #12 0x000055581f2944cb llvm::ConstantArray::get(llvm::ArrayType*, llvm::ArrayRef<llvm::Constant*>) /b/sanitizer-x86_64-linux-autoconf/build/llvm/lib/IR/Constants.cpp:964:0
    #13 0x000055581fa27e19 llvm::SmallVectorBase::size() const /b/sanitizer-x86_64-linux-autoconf/build/llvm/include/llvm/ADT/SmallVector.h:53:0
    #14 0x000055581fa27e19 llvm::SmallVectorImpl<llvm::Constant*>::resize(unsigned long) /b/sanitizer-x86_64-linux-autoconf/build/llvm/include/llvm/ADT/SmallVector.h:347:0
    #15 0x000055581fa27e19 (anonymous namespace)::EmitArrayConstant(clang::CodeGen::CodeGenModule&, clang::ConstantArrayType const*, llvm::Type*, unsigned int, llvm::SmallVectorImpl<llvm::Constant*>&, llvm::Constant*) /b/sanitizer-x86_64-linux-autoconf/build/llvm/tools/clang/lib/CodeGen/CGExprConstant.cpp:669:0

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337511 91177308-0d34-0410-b5e6-96231b3b80d8
alexcrichton pushed a commit that referenced this pull request Aug 22, 2018
Summary:
Currently, in line with GCC, when specifying reserved registers like sp or pc on an inline asm() clobber list, we don't always preserve the original value across the statement. And in general, overwriting reserved registers can have surprising results.

For example:


```
extern int bar(int[]);

int foo(int i) {
  int a[i]; // VLA
  asm volatile(
      "mov r7, #1"
    :
    :
    : "r7"
  );

  return 1 + bar(a);
}
```

Compiled for thumb, this gives:
```
$ clang --target=arm-arm-none-eabi -march=armv7a -c test.c -o - -S -O1 -mthumb
...
foo:
        .fnstart
@ %bb.0:                                @ %entry
        .save   {r4, r5, r6, r7, lr}
        push    {r4, r5, r6, r7, lr}
        .setfp  r7, sp, #12
        add     r7, sp, #12
        .pad    #4
        sub     sp, #4
        movs    r1, #7
        add.w   r0, r1, r0, lsl #2
        bic     r0, r0, #7
        sub.w   r0, sp, r0
        mov     sp, r0
        @app
        mov.w   r7, #1
        @NO_APP
        bl      bar
        adds    r0, #1
        sub.w   r4, r7, #12
        mov     sp, r4
        pop     {r4, r5, r6, r7, pc}
...
```

r7 is used as the frame pointer for thumb targets, and this function needs to restore the SP from the FP because of the variable-length stack allocation a. r7 is clobbered by the inline assembly (and r7 is included in the clobber list), but LLVM does not preserve the value of the frame pointer across the assembly block.

This type of behavior is similar to GCC's and has been discussed on the bugtracker: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11807 . No consensus seemed to have been reached on the way forward.  Clang behavior has briefly been discussed on the CFE mailing (starting here: http://lists.llvm.org/pipermail/cfe-dev/2018-July/058392.html). I've opted for following Eli Friedman's advice to print warnings when there are reserved registers on the clobber list so as not to diverge from GCC behavior for now.

The patch uses MachineRegisterInfo's target-specific knowledge of reserved registers, just before we convert the inline asm string in the AsmPrinter.

If we find a reserved register, we print a warning:
```
repro.c:6:7: warning: inline asm clobber list contains reserved registers: R7 [-Winline-asm]
      "mov r7, #1"
      ^
```

Reviewers: eli.friedman, olista01, javed.absar, efriedma

Reviewed By: efriedma

Subscribers: efriedma, eraman, kristof.beyls, llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339257 91177308-0d34-0410-b5e6-96231b3b80d8
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants