1; RUN: opt < %s -S -early-cse -earlycse-debug-hash | FileCheck %s --check-prefix=CHECK-NOMEMSSA 2; RUN: opt < %s -S -basic-aa -early-cse-memssa | FileCheck %s 3; RUN: opt < %s -S -passes='early-cse' | FileCheck %s --check-prefix=CHECK-NOMEMSSA 4; RUN: opt < %s -S -aa-pipeline=basic-aa -passes='early-cse-memssa' | FileCheck %s 5 6@G1 = global i32 zeroinitializer 7@G2 = global i32 zeroinitializer 8@G3 = global i32 zeroinitializer 9 10;; Simple load value numbering across non-clobbering store. 11; CHECK-LABEL: @test1( 12; CHECK-NOMEMSSA-LABEL: @test1( 13define i32 @test1() { 14 %V1 = load i32, i32* @G1 15 store i32 0, i32* @G2 16 %V2 = load i32, i32* @G1 17 ; CHECK-NOMEMSSA: sub i32 %V1, %V2 18 %Diff = sub i32 %V1, %V2 19 ret i32 %Diff 20 ; CHECK: ret i32 0 21} 22 23;; Simple dead store elimination across non-clobbering store. 24; CHECK-LABEL: @test2( 25; CHECK-NOMEMSSA-LABEL: @test2( 26define void @test2() { 27entry: 28 %V1 = load i32, i32* @G1 29 ; CHECK: store i32 0, i32* @G2 30 store i32 0, i32* @G2 31 ; CHECK-NOT: store 32 ; CHECK-NOMEMSSA: store i32 %V1, i32* @G1 33 store i32 %V1, i32* @G1 34 ret void 35} 36 37;; Check that memoryphi optimization happens during EarlyCSE, enabling 38;; more load CSE opportunities. 39; CHECK-LABEL: @test_memphiopt( 40; CHECK-NOMEMSSA-LABEL: @test_memphiopt( 41define void @test_memphiopt(i1 %c, i32* %p) { 42; CHECK-LABEL: entry: 43; CHECK-NOMEMSSA-LABEL: entry: 44entry: 45; CHECK: load 46; CHECK-NOMEMSSA: load 47 %v1 = load i32, i32* @G1 48 br i1 %c, label %then, label %end 49 50; CHECK-LABEL: then: 51; CHECK-NOMEMSSA-LABEL: then: 52then: 53; CHECK: load 54; CHECK-NOMEMSSA: load 55 %pv = load i32, i32* %p 56; CHECK-NOT: store 57; CHECK-NOMEMSSA-NOT: store 58 store i32 %pv, i32* %p 59 br label %end 60 61; CHECK-LABEL: end: 62; CHECK-NOMEMSSA-LABEL: end: 63end: 64; CHECK-NOT: load 65; CHECK-NOMEMSSA: load 66 %v2 = load i32, i32* @G1 67 %sum = add i32 %v1, %v2 68 store i32 %sum, i32* @G2 69 ret void 70} 71 72 73;; Check that MemoryPhi optimization and MemoryUse re-optimization 74;; happens during EarlyCSE, enabling more load CSE opportunities. 75; CHECK-LABEL: @test_memphiopt2( 76; CHECK-NOMEMSSA-LABEL: @test_memphiopt2( 77define void @test_memphiopt2(i1 %c, i32* %p) { 78; CHECK-LABEL: entry: 79; CHECK-NOMEMSSA-LABEL: entry: 80entry: 81; CHECK: load 82; CHECK-NOMEMSSA: load 83 %v1 = load i32, i32* @G1 84; CHECK: store 85; CHECK-NOMEMSSA: store 86 store i32 %v1, i32* @G2 87 br i1 %c, label %then, label %end 88 89; CHECK-LABEL: then: 90; CHECK-NOMEMSSA-LABEL: then: 91then: 92; CHECK: load 93; CHECK-NOMEMSSA: load 94 %pv = load i32, i32* %p 95; CHECK-NOT: store 96; CHECK-NOMEMSSA-NOT: store 97 store i32 %pv, i32* %p 98 br label %end 99 100; CHECK-LABEL: end: 101; CHECK-NOMEMSSA-LABEL: end: 102end: 103; CHECK-NOT: load 104; CHECK-NOMEMSSA: load 105 %v2 = load i32, i32* @G1 106 store i32 %v2, i32* @G3 107 ret void 108} 109 110;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting 111;; stores that, without the lifetime calls, would be writebacks. 112; CHECK-LABEL: @test_writeback_lifetimes( 113; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes( 114define void @test_writeback_lifetimes(i32* %p) { 115entry: 116 %q = getelementptr i32, i32* %p, i64 1 117 %pv = load i32, i32* %p 118 %qv = load i32, i32* %q 119 call void @llvm.lifetime.end.p0i8(i64 8, i32* %p) 120 call void @llvm.lifetime.start.p0i8(i64 8, i32* %p) 121 ; CHECK: store i32 %pv 122 ; CHECK-NOMEMSSA-LABEL: store i32 %pv 123 store i32 %pv, i32* %p 124 ; CHECK: store i32 %qv, i32* %q 125 ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q 126 store i32 %qv, i32* %q 127 ret void 128} 129 130;; Check that we respect lifetime.start/lifetime.end intrinsics when deleting 131;; stores that, without the lifetime calls, would be writebacks. 132; CHECK-LABEL: @test_writeback_lifetimes_multi_arg( 133; CHECK-NOMEMSSA-LABEL: @test_writeback_lifetimes_multi_arg( 134define void @test_writeback_lifetimes_multi_arg(i32* %p, i32* %q) { 135entry: 136 %pv = load i32, i32* %p 137 %qv = load i32, i32* %q 138 call void @llvm.lifetime.end.p0i8(i64 8, i32* %p) 139 call void @llvm.lifetime.start.p0i8(i64 8, i32* %p) 140 ; CHECK: store i32 %pv 141 ; CHECK-NOMEMSSA-LABEL: store i32 %pv 142 store i32 %pv, i32* %p 143 ; CHECK: store i32 %qv, i32* %q 144 ; CHECK-NOMEMSSA-LABEL: store i32 %qv, i32* %q 145 store i32 %qv, i32* %q 146 ret void 147} 148 149declare void @llvm.lifetime.end.p0i8(i64, i32*) 150declare void @llvm.lifetime.start.p0i8(i64, i32*) 151