[instcombine][unordered] Implement *-load forwarding for unordered atomics
authorPhilip Reames <listmail@philipreames.com>
Thu, 21 Apr 2016 17:03:33 +0000 (17:03 +0000)
committerPhilip Reames <listmail@philipreames.com>
Thu, 21 Apr 2016 17:03:33 +0000 (17:03 +0000)
This builds on 266999 which made FindAvailableValue do the right thing.  Tests included show the newly enabled transforms and those which disabled either due to conservatism or correctness requirements.

llvm-svn: 267006

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
llvm/test/Transforms/InstCombine/atomic.ll

index c855663..fc3de6b 100644 (file)
@@ -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);
index bf576ba..75b63ff 100644 (file)
@@ -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
+}
+