1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basic-aa -newgvn -S | FileCheck %s 3 4;; Most of these are borrowed from transforms/DSE/simple.ll 5;; NewGVN should be able to eliminate any stores of the same value that are actually redundnat. 6 7;; tmp5 is store of the same value to the same location as the load. 8define void @test12({ i32, i32 }* %x) nounwind { 9; CHECK-LABEL: @test12( 10; CHECK-NEXT: [[TMP4:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[X:%.*]], i32 0, i32 0 11; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 4 12; CHECK-NEXT: [[TMP7:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[X]], i32 0, i32 1 13; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4 14; CHECK-NEXT: [[TMP17:%.*]] = sub i32 0, [[TMP8]] 15; CHECK-NEXT: store i32 [[TMP17]], i32* [[TMP7]], align 4 16; CHECK-NEXT: ret void 17; 18 %tmp4 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 0 19 %tmp5 = load i32, i32* %tmp4, align 4 20 %tmp7 = getelementptr { i32, i32 }, { i32, i32 }* %x, i32 0, i32 1 21 %tmp8 = load i32, i32* %tmp7, align 4 22 %tmp17 = sub i32 0, %tmp8 23 store i32 %tmp5, i32* %tmp4, align 4 24 store i32 %tmp17, i32* %tmp7, align 4 25 ret void 26} 27; Remove redundant store if loaded value is in another block. 28define i32 @test26(i1 %c, i32* %p) { 29; CHECK-LABEL: @test26( 30; CHECK-NEXT: entry: 31; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 32; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] 33; CHECK: bb1: 34; CHECK-NEXT: br label [[BB3:%.*]] 35; CHECK: bb2: 36; CHECK-NEXT: br label [[BB3]] 37; CHECK: bb3: 38; CHECK-NEXT: ret i32 0 39; 40entry: 41 %v = load i32, i32* %p, align 4 42 br i1 %c, label %bb1, label %bb2 43bb1: 44 br label %bb3 45bb2: 46 store i32 %v, i32* %p, align 4 47 br label %bb3 48bb3: 49 ret i32 0 50} 51 52declare void @unknown_func() 53; Remove redundant store, which is in the same loop as the load. 54define i32 @test33(i1 %c, i32* %p, i32 %i) { 55; CHECK-LABEL: @test33( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: br label [[BB1:%.*]] 58; CHECK: bb1: 59; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P:%.*]], align 4 60; CHECK-NEXT: br label [[BB2:%.*]] 61; CHECK: bb2: 62; CHECK-NEXT: call void @unknown_func() 63; CHECK-NEXT: br i1 undef, label [[BB1]], label [[BB3:%.*]] 64; CHECK: bb3: 65; CHECK-NEXT: ret i32 0 66; 67entry: 68 br label %bb1 69bb1: 70 %v = load i32, i32* %p, align 4 71 br label %bb2 72bb2: 73 store i32 %v, i32* %p, align 4 74 ; Might read and overwrite value at %p, but doesn't matter. 75 call void @unknown_func() 76 br i1 undef, label %bb1, label %bb3 77bb3: 78 ret i32 0 79} 80