Index: llvm/lib/Transforms/Scalar/GVNHoist.cpp =================================================================== --- llvm/lib/Transforms/Scalar/GVNHoist.cpp +++ llvm/lib/Transforms/Scalar/GVNHoist.cpp @@ -936,10 +936,17 @@ HoistingPointList HPL; computeInsertionPoints(II.getVNTable(), HPL, InsKind::Scalar); computeInsertionPoints(LI.getVNTable(), HPL, InsKind::Load); - computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store); computeInsertionPoints(CI.getScalarVNTable(), HPL, InsKind::Scalar); computeInsertionPoints(CI.getLoadVNTable(), HPL, InsKind::Load); - computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store); + + // Hoisting stores is difficult: see PR30216; disabled until either we fix + // the dependence analysis, or we decide to only sink the stores. In + // principle stores should be by default sinked, unless doing so would + // increase the live range of stored values. + if (0) { + computeInsertionPoints(SI.getVNTable(), HPL, InsKind::Store); + computeInsertionPoints(CI.getStoreVNTable(), HPL, InsKind::Store); + } return hoist(HPL); } }; Index: llvm/test/Transforms/GVNHoist/hoist-md.ll =================================================================== --- llvm/test/Transforms/GVNHoist/hoist-md.ll +++ llvm/test/Transforms/GVNHoist/hoist-md.ll @@ -18,8 +18,7 @@ ret void } ; CHECK-LABEL: define void @test1( -; CHECK: store i32 2, i32* %x, align 4 -; CHECK-NEXT: br i1 %b +; Store hoisting is disabled. define void @test2(i1 %b, i32* %x) { entry: @@ -39,9 +38,7 @@ ret void } ; CHECK-LABEL: define void @test2( -; CHECK: %[[gep:.*]] = getelementptr inbounds i32, i32* %x, i64 1 -; CHECK: store i32 2, i32* %[[gep]], align 4 -; CHECK-NEXT: br i1 %b +; Store hoisting is disabled. define void @test3(i1 %b, i32* %x) { entry: @@ -61,9 +58,7 @@ ret void } ; CHECK-LABEL: define void @test3( -; CHECK: %[[gep:.*]] = getelementptr i32, i32* %x, i64 1 -; CHECK: store i32 2, i32* %[[gep]], align 4 -; CHECK-NEXT: br i1 %b +; Store hoisting is disabled. !1 = !{!2, !2, i64 0} !2 = !{!"int", !3, i64 0} Index: llvm/test/Transforms/GVNHoist/hoist-mssa.ll =================================================================== --- llvm/test/Transforms/GVNHoist/hoist-mssa.ll +++ llvm/test/Transforms/GVNHoist/hoist-mssa.ll @@ -1,9 +1,9 @@ ; RUN: opt -S -gvn-hoist < %s | FileCheck %s -; Check that store hoisting works: there should be only one store left. +; Store hoisting is disabled. ; CHECK-LABEL: @getopt ; CHECK: store i32 -; CHECK-NOT: store i32 +; CHECK: store i32 @optind = external global i32, align 4 @@ -49,10 +49,10 @@ @GlobalVar = internal global float 1.000000e+00 -; Check that we hoist stores and remove the MSSA phi node. +; Store hoisting is disabled. ; CHECK-LABEL: @hoistStoresUpdateMSSA ; CHECK: store float -; CHECK-NOT: store float +; CHECK: store float define float @hoistStoresUpdateMSSA(float %d) { entry: store float 0.000000e+00, float* @GlobalVar Index: llvm/test/Transforms/GVNHoist/hoist-pr28606.ll =================================================================== --- llvm/test/Transforms/GVNHoist/hoist-pr28606.ll +++ llvm/test/Transforms/GVNHoist/hoist-pr28606.ll @@ -17,9 +17,9 @@ ; CHECK: alloca inalloca ; CHECK-NOT: alloca i8 -; Check that store instructions are hoisted. +; Store hoisting is disabled. +; CHECK: store i8 ; CHECK: store i8 -; CHECK-NOT: store i8 ; CHECK: stackrestore define void @test(i1 %b) { Index: llvm/test/Transforms/GVNHoist/hoist-pr28933.ll =================================================================== --- llvm/test/Transforms/GVNHoist/hoist-pr28933.ll +++ llvm/test/Transforms/GVNHoist/hoist-pr28933.ll @@ -1,11 +1,11 @@ ; RUN: opt -S -gvn-hoist -verify-memoryssa < %s | FileCheck %s -; Check that we end up with one load and one store, in the right order +; Store hoisting is disabled. ; CHECK-LABEL: define void @test_it( ; CHECK: store ; CHECK-NEXT: load -; CHECK-NOT: store -; CHECK-NOT: load +; CHECK: store +; CHECK: load %rec894.0.1.2.3.12 = type { i16 } Index: llvm/test/Transforms/GVNHoist/hoist.ll =================================================================== --- llvm/test/Transforms/GVNHoist/hoist.ll +++ llvm/test/Transforms/GVNHoist/hoist.ll @@ -627,24 +627,8 @@ ret float %add } -; Check that we hoist stores: all the instructions from the then branch -; should be hoisted. +; Store hoisting is disabled. ; CHECK-LABEL: @hoistStores -; CHECK: zext -; CHECK-NEXT: trunc -; CHECK-NEXT: getelementptr -; CHECK-NEXT: load -; CHECK-NEXT: getelementptr -; CHECK-NEXT: getelementptr -; CHECK-NEXT: store -; CHECK-NEXT: load -; CHECK-NEXT: load -; CHECK-NEXT: zext -; CHECK-NEXT: add -; CHECK-NEXT: store -; CHECK-NEXT: br -; CHECK: if.then -; CHECK: br %struct.foo = type { i16* } Index: llvm/test/Transforms/GVNHoist/pr30216.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/GVNHoist/pr30216.ll @@ -0,0 +1,26 @@ +; RUN: opt -S -gvn-hoist < %s | FileCheck %s + +; Make sure the two stores @B do not get hoisted past the load @B. + +; CHECK-LABEL: define i8* @Foo +; CHECK: store +; CHECK: store +; CHECK: load +; CHECK: store + +@A = external global i8 +@B = external global i8* + +define i8* @Foo() { + store i8 0, i8* @A + br i1 undef, label %if.then, label %if.else + +if.then: + store i8* null, i8** @B + ret i8* null + +if.else: + %1 = load i8*, i8** @B + store i8* null, i8** @B + ret i8* %1 +}