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