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 7define 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 13bb26: ; 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 18bb68: ; 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 27bb77: ; 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 36define 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 43bb26: ; 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 48bb68: ; 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 57bb77: ; 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 67define 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 73bb26: ; 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 78bb68: ; 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 87bb77: ; 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 96define 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 102bb26: ; 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 109bb68: ; 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 118bb77: ; 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 127define 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 133bb26: ; 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 140bb68: ; 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 149bb77: ; preds = %bb68, %bb26 150; CHECK: 2 = MemoryPhi({bb26,3},{bb68,1}) 151; CHECK-NEXT: br label %bb26 152 br label %bb26 153} 154 155attributes #0 = { "null-pointer-is-valid"="true" } 156