diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 10 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/atomic.ll | 51 |
2 files changed, 58 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index fc3de6b49f3..981dfc12491 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -836,9 +836,9 @@ 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; + // None of the following transforms are legal for volatile/ordered atomic + // loads. Most of them do apply for unordered atomics. + if (!LI.isUnordered()) return nullptr; // load(gep null, ...) -> unreachable if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) { @@ -867,6 +867,10 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { return replaceInstUsesWith(LI, UndefValue::get(LI.getType())); } + // TODO: The transform below needs updated for unordered loads + if (!LI.isSimple()) + return nullptr; + if (Op->hasOneUse()) { // Change select and PHI nodes to select values instead of addresses: this // helps alias analysis out a lot, allows many others simplifications, and diff --git a/llvm/test/Transforms/InstCombine/atomic.ll b/llvm/test/Transforms/InstCombine/atomic.ll index 75b63ff36ab..1d24248e73e 100644 --- a/llvm/test/Transforms/InstCombine/atomic.ll +++ b/llvm/test/Transforms/InstCombine/atomic.ll @@ -93,3 +93,54 @@ define i32 @test8(i32* %p) { ret i32 %z } +; An unordered access to null is still unreachable. There's no +; ordering imposed. +define i32 @test9() { +; CHECK-LABEL: define i32 @test9( +; CHECK: store i32 undef, i32* null + %x = load atomic i32, i32* null unordered, align 4 + ret i32 %x +} + +; FIXME: Could also fold +define i32 @test10() { +; CHECK-LABEL: define i32 @test10( +; CHECK: load atomic i32, i32* null monotonic + %x = load atomic i32, i32* null monotonic, align 4 + ret i32 %x +} + +; Would this be legal to fold? Probably? +define i32 @test11() { +; CHECK-LABEL: define i32 @test11( +; CHECK: load atomic i32, i32* null seq_cst + %x = load atomic i32, i32* null seq_cst, align 4 + ret i32 %x +} + +; An unordered access to null is still unreachable. There's no +; ordering imposed. +define i32 @test12() { +; CHECK-LABEL: define i32 @test12( +; CHECK: store atomic i32 undef, i32* null + store atomic i32 0, i32* null unordered, align 4 + ret i32 0 +} + +; FIXME: Could also fold +define i32 @test13() { +; CHECK-LABEL: define i32 @test13( +; CHECK: store atomic i32 0, i32* null monotonic + store atomic i32 0, i32* null monotonic, align 4 + ret i32 0 +} + +; Would this be legal to fold? Probably? +define i32 @test14() { +; CHECK-LABEL: define i32 @test14( +; CHECK: store atomic i32 0, i32* null seq_cst + store atomic i32 0, i32* null seq_cst, align 4 + ret i32 0 +} + + |