diff options
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/atomic.ll | 37 |
2 files changed, 39 insertions, 6 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index c8556638cec..fc3de6b49f3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -809,10 +809,6 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { return &LI; } - // None of the following transforms are legal for volatile/atomic loads. - // FIXME: Some of it is okay for atomic loads; needs refactoring. - if (!LI.isSimple()) return nullptr; - if (Instruction *Res = unpackLoadToAggregate(*this, LI)) return Res; @@ -840,6 +836,10 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { LI.getName() + ".cast")); } + // None of the following transforms are legal for volatile/atomic loads. + // FIXME: Some of it is okay for atomic loads; needs refactoring. + if (!LI.isSimple()) return nullptr; + // load(gep null, ...) -> unreachable if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) { const Value *GEPI0 = GEPI->getOperand(0); diff --git a/llvm/test/Transforms/InstCombine/atomic.ll b/llvm/test/Transforms/InstCombine/atomic.ll index bf576ba4b3a..75b63ff36ab 100644 --- a/llvm/test/Transforms/InstCombine/atomic.ll +++ b/llvm/test/Transforms/InstCombine/atomic.ll @@ -37,11 +37,11 @@ define i32 @test3(i32* %p) { ret i32 %z } -; FIXME: Forwarding from a stronger atomic is fine +; Forwarding from a stronger ordered atomic is fine define i32 @test4(i32* %p) { ; CHECK-LABEL: define i32 @test4( ; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 -; CHECK: %y = load atomic i32, i32* %p unordered, align 4 +; CHECK: shl i32 %x, 1 %x = load atomic i32, i32* %p seq_cst, align 4 %y = load atomic i32, i32* %p unordered, align 4 %z = add i32 %x, %y @@ -60,3 +60,36 @@ define i32 @test5(i32* %p) { ret i32 %z } +; Forwarding atomic to atomic is fine +define i32 @test6(i32* %p) { +; CHECK-LABEL: define i32 @test6( +; CHECK: %x = load atomic i32, i32* %p unordered, align 4 +; CHECK: shl i32 %x, 1 + %x = load atomic i32, i32* %p unordered, align 4 + %y = load atomic i32, i32* %p unordered, align 4 + %z = add i32 %x, %y + ret i32 %z +} + +; FIXME: we currently don't do anything for monotonic +define i32 @test7(i32* %p) { +; CHECK-LABEL: define i32 @test7( +; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 +; CHECK: %y = load atomic i32, i32* %p monotonic, align 4 + %x = load atomic i32, i32* %p seq_cst, align 4 + %y = load atomic i32, i32* %p monotonic, align 4 + %z = add i32 %x, %y + ret i32 %z +} + +; FIXME: We could forward in racy code +define i32 @test8(i32* %p) { +; CHECK-LABEL: define i32 @test8( +; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4 +; CHECK: %y = load atomic i32, i32* %p acquire, align 4 + %x = load atomic i32, i32* %p seq_cst, align 4 + %y = load atomic i32, i32* %p acquire, align 4 + %z = add i32 %x, %y + ret i32 %z +} + |

