summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp8
-rw-r--r--llvm/test/Transforms/InstCombine/atomic.ll37
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
+}
+
OpenPOWER on IntegriCloud