1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG 3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG 4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64" 5 6@a = external global i16, align 1 7 8declare void @maybe_writes() 9 10define void @f2(i1 %c1) { 11; CHECK-LABEL: @f2( 12; CHECK-NEXT: entry: 13; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 14; CHECK: if.then: 15; CHECK-NEXT: br label [[CLEANUP:%.*]] 16; CHECK: cleanup: 17; CHECK-NEXT: [[G_0_SROA_SPECULATE_LOAD_CLEANUP:%.*]] = load i16, ptr @a, align 1 18; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 19; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 20; CHECK-NEXT: i32 2, label [[LBL1]] 21; CHECK-NEXT: ] 22; CHECK: if.else: 23; CHECK-NEXT: br label [[LBL1]] 24; CHECK: lbl1: 25; CHECK-NEXT: [[G_0_SROA_SPECULATED:%.*]] = phi i16 [ [[G_0_SROA_SPECULATE_LOAD_CLEANUP]], [[CLEANUP]] ], [ [[G_0_SROA_SPECULATE_LOAD_CLEANUP]], [[CLEANUP]] ], [ undef, [[IF_ELSE]] ] 26; CHECK-NEXT: unreachable 27; CHECK: cleanup7: 28; CHECK-NEXT: ret void 29; 30entry: 31 %e = alloca i16, align 1 32 br i1 %c1, label %if.then, label %if.else 33 34if.then: ; preds = %entry 35 br label %cleanup 36 37cleanup: ; preds = %if.then 38 switch i32 2, label %cleanup7 [ 39 i32 0, label %lbl1 40 i32 2, label %lbl1 41 ] 42 43if.else: ; preds = %entry 44 br label %lbl1 45 46lbl1: ; preds = %if.else, %cleanup, %cleanup 47 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 48 %0 = load i16, ptr %g.0, align 1 49 unreachable 50 51cleanup7: ; preds = %cleanup 52 ret void 53} 54 55define void @f2_hwasan(i1 %c1) sanitize_hwaddress { 56; CHECK-LABEL: @f2_hwasan( 57; CHECK-NEXT: entry: 58; CHECK-NEXT: [[E:%.*]] = alloca i16, align 1 59; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 60; CHECK: if.then: 61; CHECK-NEXT: br label [[CLEANUP:%.*]] 62; CHECK: cleanup: 63; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 64; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 65; CHECK-NEXT: i32 2, label [[LBL1]] 66; CHECK-NEXT: ] 67; CHECK: if.else: 68; CHECK-NEXT: br label [[LBL1]] 69; CHECK: lbl1: 70; CHECK-NEXT: [[G_0:%.*]] = phi ptr [ @a, [[CLEANUP]] ], [ @a, [[CLEANUP]] ], [ [[E]], [[IF_ELSE]] ] 71; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[G_0]], align 1 72; CHECK-NEXT: unreachable 73; CHECK: cleanup7: 74; CHECK-NEXT: ret void 75; 76entry: 77 %e = alloca i16, align 1 78 br i1 %c1, label %if.then, label %if.else 79 80if.then: ; preds = %entry 81 br label %cleanup 82 83cleanup: ; preds = %if.then 84 switch i32 2, label %cleanup7 [ 85 i32 0, label %lbl1 86 i32 2, label %lbl1 87 ] 88 89if.else: ; preds = %entry 90 br label %lbl1 91 92lbl1: ; preds = %if.else, %cleanup, %cleanup 93 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 94 %0 = load i16, ptr %g.0, align 1 95 unreachable 96 97cleanup7: ; preds = %cleanup 98 ret void 99} 100 101define void @f3(i1 %c1) { 102; CHECK-LABEL: @f3( 103; CHECK-NEXT: entry: 104; CHECK-NEXT: [[E:%.*]] = alloca i16, align 1 105; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 106; CHECK: if.then: 107; CHECK-NEXT: br label [[CLEANUP:%.*]] 108; CHECK: cleanup: 109; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 110; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 111; CHECK-NEXT: i32 2, label [[LBL1]] 112; CHECK-NEXT: ] 113; CHECK: if.else: 114; CHECK-NEXT: br label [[LBL1]] 115; CHECK: lbl1: 116; CHECK-NEXT: [[G_0:%.*]] = phi ptr [ @a, [[CLEANUP]] ], [ @a, [[CLEANUP]] ], [ [[E]], [[IF_ELSE]] ] 117; CHECK-NEXT: br label [[FINAL:%.*]] 118; CHECK: final: 119; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[G_0]], align 1 120; CHECK-NEXT: unreachable 121; CHECK: cleanup7: 122; CHECK-NEXT: ret void 123; 124entry: 125 %e = alloca i16, align 1 126 br i1 %c1, label %if.then, label %if.else 127 128if.then: ; preds = %entry 129 br label %cleanup 130 131cleanup: ; preds = %if.then 132 switch i32 2, label %cleanup7 [ 133 i32 0, label %lbl1 134 i32 2, label %lbl1 135 ] 136 137if.else: ; preds = %entry 138 br label %lbl1 139 140lbl1: ; preds = %if.else, %cleanup, %cleanup 141 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 142 br label %final 143 144final: 145 %0 = load i16, ptr %g.0, align 1 146 unreachable 147 148cleanup7: ; preds = %cleanup 149 ret void 150} 151 152define void @f4(i1 %c1) { 153; CHECK-LABEL: @f4( 154; CHECK-NEXT: entry: 155; CHECK-NEXT: [[E:%.*]] = alloca i16, align 1 156; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 157; CHECK: if.then: 158; CHECK-NEXT: br label [[CLEANUP:%.*]] 159; CHECK: cleanup: 160; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 161; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 162; CHECK-NEXT: i32 2, label [[LBL1]] 163; CHECK-NEXT: ] 164; CHECK: if.else: 165; CHECK-NEXT: br label [[LBL1]] 166; CHECK: lbl1: 167; CHECK-NEXT: [[G_0:%.*]] = phi ptr [ @a, [[CLEANUP]] ], [ @a, [[CLEANUP]] ], [ [[E]], [[IF_ELSE]] ] 168; CHECK-NEXT: br label [[FINAL:%.*]] 169; CHECK: final: 170; CHECK-NEXT: call void @maybe_writes() 171; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[G_0]], align 1 172; CHECK-NEXT: unreachable 173; CHECK: cleanup7: 174; CHECK-NEXT: ret void 175; 176entry: 177 %e = alloca i16, align 1 178 br i1 %c1, label %if.then, label %if.else 179 180if.then: ; preds = %entry 181 br label %cleanup 182 183cleanup: ; preds = %if.then 184 switch i32 2, label %cleanup7 [ 185 i32 0, label %lbl1 186 i32 2, label %lbl1 187 ] 188 189if.else: ; preds = %entry 190 br label %lbl1 191 192lbl1: ; preds = %if.else, %cleanup, %cleanup 193 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 194 br label %final 195 196final: 197 call void @maybe_writes() 198 %0 = load i16, ptr %g.0, align 1 199 unreachable 200 201cleanup7: ; preds = %cleanup 202 ret void 203} 204 205define void @f5(i1 %c1, i1 %c2) { 206; CHECK-LABEL: @f5( 207; CHECK-NEXT: entry: 208; CHECK-NEXT: [[E:%.*]] = alloca i16, align 1 209; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 210; CHECK: if.then: 211; CHECK-NEXT: br label [[CLEANUP:%.*]] 212; CHECK: cleanup: 213; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 214; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 215; CHECK-NEXT: i32 2, label [[LBL1]] 216; CHECK-NEXT: ] 217; CHECK: if.else: 218; CHECK-NEXT: br label [[LBL1]] 219; CHECK: lbl1: 220; CHECK-NEXT: [[G_0:%.*]] = phi ptr [ @a, [[CLEANUP]] ], [ @a, [[CLEANUP]] ], [ [[E]], [[IF_ELSE]] ] 221; CHECK-NEXT: br i1 [[C2:%.*]], label [[FINAL:%.*]], label [[CLEANUP7]] 222; CHECK: final: 223; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[G_0]], align 1 224; CHECK-NEXT: unreachable 225; CHECK: cleanup7: 226; CHECK-NEXT: ret void 227; 228entry: 229 %e = alloca i16, align 1 230 br i1 %c1, label %if.then, label %if.else 231 232if.then: ; preds = %entry 233 br label %cleanup 234 235cleanup: ; preds = %if.then 236 switch i32 2, label %cleanup7 [ 237 i32 0, label %lbl1 238 i32 2, label %lbl1 239 ] 240 241if.else: ; preds = %entry 242 br label %lbl1 243 244lbl1: ; preds = %if.else, %cleanup, %cleanup 245 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 246 br i1 %c2, label %final, label %cleanup7 247 248final: 249 %0 = load i16, ptr %g.0, align 1 250 unreachable 251 252cleanup7: ; preds = %cleanup 253 ret void 254} 255 256define void @f6(i1 %c1) { 257; CHECK-LABEL: @f6( 258; CHECK-NEXT: entry: 259; CHECK-NEXT: [[E:%.*]] = alloca i16, align 1 260; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 261; CHECK: if.then: 262; CHECK-NEXT: br label [[CLEANUP:%.*]] 263; CHECK: cleanup: 264; CHECK-NEXT: switch i32 2, label [[CLEANUP7:%.*]] [ 265; CHECK-NEXT: i32 0, label [[LBL1:%.*]] 266; CHECK-NEXT: i32 2, label [[LBL1]] 267; CHECK-NEXT: ] 268; CHECK: if.else: 269; CHECK-NEXT: br label [[LBL1]] 270; CHECK: lbl1: 271; CHECK-NEXT: [[G_0:%.*]] = phi ptr [ @a, [[CLEANUP]] ], [ @a, [[CLEANUP]] ], [ [[E]], [[IF_ELSE]] ] 272; CHECK-NEXT: br label [[FINAL:%.*]] 273; CHECK: unreachable_pred: 274; CHECK-NEXT: br label [[FINAL]] 275; CHECK: final: 276; CHECK-NEXT: call void @maybe_writes() 277; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[G_0]], align 1 278; CHECK-NEXT: unreachable 279; CHECK: cleanup7: 280; CHECK-NEXT: ret void 281; 282entry: 283 %e = alloca i16, align 1 284 br i1 %c1, label %if.then, label %if.else 285 286if.then: ; preds = %entry 287 br label %cleanup 288 289cleanup: ; preds = %if.then 290 switch i32 2, label %cleanup7 [ 291 i32 0, label %lbl1 292 i32 2, label %lbl1 293 ] 294 295if.else: ; preds = %entry 296 br label %lbl1 297 298lbl1: ; preds = %if.else, %cleanup, %cleanup 299 %g.0 = phi ptr [ @a, %cleanup ], [ @a, %cleanup ], [ %e, %if.else ] 300 br label %final 301 302unreachable_pred: 303 br label %final 304 305final: 306 call void @maybe_writes() 307 %0 = load i16, ptr %g.0, align 1 308 unreachable 309 310cleanup7: ; preds = %cleanup 311 ret void 312} 313;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: 314; CHECK-MODIFY-CFG: {{.*}} 315; CHECK-PRESERVE-CFG: {{.*}} 316