1 ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s 2 ; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>,verify<memoryssa>' -disable-output < %s 2>&1 | FileCheck %s 3 4 %struct.hoge = type { i32, %struct.widget } 5 %struct.widget = type { i64 } 6 7 define hidden void @quux(%struct.hoge *%f) align 2 { 8 %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0 9 %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1 10 %tmp25 = bitcast %struct.widget* %tmp24 to i64** 11 br label %bb26 12 13 bb26: ; preds = %bb77, %0 14 ; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2}) 15 ; CHECK-NEXT: br i1 undef, label %bb68, label %bb77 16 br i1 undef, label %bb68, label %bb77 17 18 bb68: ; preds = %bb26 19 ; CHECK: MemoryUse(liveOnEntry) 20 ; CHECK-NEXT: %tmp69 = load i64, i64* null, align 8 21 %tmp69 = load i64, i64* null, align 8 22 ; CHECK: 1 = MemoryDef(3) 23 ; CHECK-NEXT: store i64 %tmp69, i64* %tmp, align 8 24 store i64 %tmp69, i64* %tmp, align 8 25 br label %bb77 26 27 bb77: ; preds = %bb68, %bb26 28 ; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1}) 29 ; CHECK: MemoryUse(2) 30 ; CHECK-NEXT: %tmp78 = load i64*, i64** %tmp25, align 8 31 %tmp78 = load i64*, i64** %tmp25, align 8 32 %tmp79 = getelementptr inbounds i64, i64* %tmp78, i64 undef 33 br label %bb26 34 } 35 36 define hidden void @quux_no_null_opt(%struct.hoge *%f) align 2 #0 { 37 ; CHECK-LABEL: quux_no_null_opt( 38 %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0 39 %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1 40 %tmp25 = bitcast %struct.widget* %tmp24 to i64** 41 br label %bb26 42 43 bb26: ; preds = %bb77, %0 44 ; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2}) 45 ; CHECK-NEXT: br i1 undef, label %bb68, label %bb77 46 br i1 undef, label %bb68, label %bb77 47 48 bb68: ; preds = %bb26 49 ; CHECK: MemoryUse(3) 50 ; CHECK-NEXT: %tmp69 = load i64, i64* null, align 8 51 %tmp69 = load i64, i64* null, align 8 52 ; CHECK: 1 = MemoryDef(3) 53 ; CHECK-NEXT: store i64 %tmp69, i64* %tmp, align 8 54 store i64 %tmp69, i64* %tmp, align 8 55 br label %bb77 56 57 bb77: ; preds = %bb68, %bb26 58 ; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1}) 59 ; CHECK: MemoryUse(2) 60 ; CHECK-NEXT: %tmp78 = load i64*, i64** %tmp25, align 8 61 %tmp78 = load i64*, i64** %tmp25, align 8 62 %tmp79 = getelementptr inbounds i64, i64* %tmp78, i64 undef 63 br label %bb26 64 } 65 66 ; CHECK-LABEL: define void @quux_skip 67 define void @quux_skip(%struct.hoge* noalias %f, i64* noalias %g) align 2 { 68 %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0 69 %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1 70 %tmp25 = bitcast %struct.widget* %tmp24 to i64** 71 br label %bb26 72 73 bb26: ; preds = %bb77, %0 74 ; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2}) 75 ; CHECK-NEXT: br i1 undef, label %bb68, label %bb77 76 br i1 undef, label %bb68, label %bb77 77 78 bb68: ; preds = %bb26 79 ; CHECK: MemoryUse(3) 80 ; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8 81 %tmp69 = load i64, i64* %g, align 8 82 ; CHECK: 1 = MemoryDef(3) 83 ; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8 84 store i64 %tmp69, i64* %g, align 8 85 br label %bb77 86 87 bb77: ; preds = %bb68, %bb26 88 ; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1}) 89 ; CHECK: MemoryUse(liveOnEntry) 90 ; CHECK-NEXT: %tmp78 = load i64*, i64** %tmp25, align 8 91 %tmp78 = load i64*, i64** %tmp25, align 8 92 br label %bb26 93 } 94 95 ; CHECK-LABEL: define void @quux_dominated 96 define void @quux_dominated(%struct.hoge* noalias %f, i64* noalias %g) align 2 { 97 %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0 98 %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1 99 %tmp25 = bitcast %struct.widget* %tmp24 to i64** 100 br label %bb26 101 102 bb26: ; preds = %bb77, %0 103 ; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2}) 104 ; CHECK: MemoryUse(3) 105 ; CHECK-NEXT: load i64*, i64** %tmp25, align 8 106 load i64*, i64** %tmp25, align 8 107 br i1 undef, label %bb68, label %bb77 108 109 bb68: ; preds = %bb26 110 ; CHECK: MemoryUse(3) 111 ; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8 112 %tmp69 = load i64, i64* %g, align 8 113 ; CHECK: 1 = MemoryDef(3) 114 ; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8 115 store i64 %tmp69, i64* %g, align 8 116 br label %bb77 117 118 bb77: ; preds = %bb68, %bb26 119 ; CHECK: 4 = MemoryPhi({bb26,3},{bb68,1}) 120 ; CHECK: 2 = MemoryDef(4) 121 ; CHECK-NEXT: store i64* null, i64** %tmp25, align 8 122 store i64* null, i64** %tmp25, align 8 123 br label %bb26 124 } 125 126 ; CHECK-LABEL: define void @quux_nodominate 127 define void @quux_nodominate(%struct.hoge* noalias %f, i64* noalias %g) align 2 { 128 %tmp = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1, i32 0 129 %tmp24 = getelementptr inbounds %struct.hoge, %struct.hoge* %f, i64 0, i32 1 130 %tmp25 = bitcast %struct.widget* %tmp24 to i64** 131 br label %bb26 132 133 bb26: ; preds = %bb77, %0 134 ; CHECK: 3 = MemoryPhi({%0,liveOnEntry},{bb77,2}) 135 ; CHECK: MemoryUse(liveOnEntry) 136 ; CHECK-NEXT: load i64*, i64** %tmp25, align 8 137 load i64*, i64** %tmp25, align 8 138 br i1 undef, label %bb68, label %bb77 139 140 bb68: ; preds = %bb26 141 ; CHECK: MemoryUse(3) 142 ; CHECK-NEXT: %tmp69 = load i64, i64* %g, align 8 143 %tmp69 = load i64, i64* %g, align 8 144 ; CHECK: 1 = MemoryDef(3) 145 ; CHECK-NEXT: store i64 %tmp69, i64* %g, align 8 146 store i64 %tmp69, i64* %g, align 8 147 br label %bb77 148 149 bb77: ; preds = %bb68, %bb26 150 ; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1}) 151 ; CHECK-NEXT: br label %bb26 152 br label %bb26 153 } 154 155 attributes #0 = { "null-pointer-is-valid"="true" } 156