Remove readnone from invariant.group.barrier
authorPiotr Padlewski <piotr.padlewski@gmail.com>
Wed, 12 Apr 2017 20:45:12 +0000 (20:45 +0000)
committerPiotr Padlewski <piotr.padlewski@gmail.com>
Wed, 12 Apr 2017 20:45:12 +0000 (20:45 +0000)
commit04aee46779f062ed45245b9b675d1b3bd4224ae3
tree461fbe6ca5d4b53f7268941415797566c74bd349
parent7a3a6e26c672a18be0d87b4c0c678eb083bc0cf7
Remove readnone from invariant.group.barrier

Summary:
Readnone attribute would cause CSE of two barriers with
the same argument, which is invalid by example:

    struct Base {
          virtual int foo() { return 42; }
    };

    struct Derived1 : Base {
          int foo() override { return 50; }
    };

    struct Derived2 : Base {
          int foo() override { return 100; }
    };

    void foo() {
        Base *x = new Base{};
        new (x) Derived1{};
        int a = std::launder(x)->foo();
        new (x) Derived2{};
        int b = std::launder(x)->foo();
    }

Here 2 calls of std::launder will produce @llvm.invariant.group.barrier,
which would be merged into one call, causing devirtualization
to devirtualize second call into Derived1::foo() instead of
Derived2::foo()

Reviewers: chandlerc, dberlin, hfinkel

Subscribers: llvm-commits, rsmith, amharc

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

llvm-svn: 300101
llvm/include/llvm/IR/Intrinsics.td
llvm/test/Analysis/MemorySSA/invariant-groups.ll
llvm/test/Other/invariant.group.barrier.ll [new file with mode: 0644]