1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -scoped-noalias-aa -slp-vectorizer -mtriple=arm64-apple-darwin -enable-new-pm=false -S %s | FileCheck %s 3; RUN: opt -aa-pipeline='basic-aa,scoped-noalias-aa' -passes=slp-vectorizer -mtriple=arm64-apple-darwin -S %s | FileCheck %s 4 5define void @needs_versioning_not_profitable(i32* %dst, i32* %src) { 6; CHECK-LABEL: @needs_versioning_not_profitable( 7; CHECK-NEXT: entry: 8; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 9; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 10; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 11; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 12; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 13; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 14; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 15; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 16; CHECK-NEXT: ret void 17; 18entry: 19 %src.0 = load i32, i32* %src, align 4 20 %r.0 = ashr i32 %src.0, 16 21 store i32 %r.0, i32* %dst, align 4 22 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 23 %src.1 = load i32, i32* %src.gep.1, align 4 24 %r.1 = ashr i32 %src.1, 16 25 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 26 store i32 %r.1, i32* %dst.gep.1, align 4 27 ret void 28} 29 30define void @needs_versioning_profitable(i32* %dst, i32* %src) { 31; CHECK-LABEL: @needs_versioning_profitable( 32; CHECK-NEXT: entry: 33; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 34; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 35; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 36; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 37; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 38; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 39; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 40; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 41; CHECK-NEXT: [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 42; CHECK-NEXT: [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4 43; CHECK-NEXT: [[R_2:%.*]] = ashr i32 [[SRC_2]], 16 44; CHECK-NEXT: [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2 45; CHECK-NEXT: store i32 [[R_2]], i32* [[DST_GEP_2]], align 4 46; CHECK-NEXT: [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 47; CHECK-NEXT: [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4 48; CHECK-NEXT: [[R_3:%.*]] = ashr i32 [[SRC_3]], 16 49; CHECK-NEXT: [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3 50; CHECK-NEXT: store i32 [[R_3]], i32* [[DST_GEP_3]], align 4 51; CHECK-NEXT: ret void 52; 53entry: 54 %src.0 = load i32, i32* %src, align 4 55 %r.0 = ashr i32 %src.0, 16 56 store i32 %r.0, i32* %dst, align 4 57 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 58 %src.1 = load i32, i32* %src.gep.1, align 4 59 %r.1 = ashr i32 %src.1, 16 60 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 61 store i32 %r.1, i32* %dst.gep.1, align 4 62 %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2 63 %src.2 = load i32, i32* %src.gep.2, align 4 64 %r.2 = ashr i32 %src.2, 16 65 %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2 66 store i32 %r.2, i32* %dst.gep.2, align 4 67 %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3 68 %src.3 = load i32, i32* %src.gep.3, align 4 69 %r.3 = ashr i32 %src.3, 16 70 %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3 71 store i32 %r.3, i32* %dst.gep.3, align 4 72 73 ret void 74} 75 76define void @needs_versioning_profitable_2_sources(i32* %dst, i32* %A, i32* %B) { 77; CHECK-LABEL: @needs_versioning_profitable_2_sources( 78; CHECK-NEXT: entry: 79; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* [[A:%.*]], align 4 80; CHECK-NEXT: [[B_0:%.*]] = load i32, i32* [[B:%.*]], align 4 81; CHECK-NEXT: [[R_0:%.*]] = add i32 [[A_0]], [[B_0]] 82; CHECK-NEXT: [[MUL_0:%.*]] = mul i32 [[R_0]], 2 83; CHECK-NEXT: store i32 [[MUL_0]], i32* [[DST:%.*]], align 4 84; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 1 85; CHECK-NEXT: [[A_1:%.*]] = load i32, i32* [[A_GEP_1]], align 4 86; CHECK-NEXT: [[B_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 1 87; CHECK-NEXT: [[B_1:%.*]] = load i32, i32* [[B_GEP_1]], align 4 88; CHECK-NEXT: [[R_1:%.*]] = add i32 [[A_1]], [[B_1]] 89; CHECK-NEXT: [[MUL_1:%.*]] = mul i32 [[R_1]], 2 90; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 91; CHECK-NEXT: store i32 [[MUL_1]], i32* [[DST_GEP_1]], align 4 92; CHECK-NEXT: [[A_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 2 93; CHECK-NEXT: [[A_2:%.*]] = load i32, i32* [[A_GEP_2]], align 4 94; CHECK-NEXT: [[B_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 2 95; CHECK-NEXT: [[B_2:%.*]] = load i32, i32* [[B_GEP_2]], align 4 96; CHECK-NEXT: [[R_2:%.*]] = add i32 [[A_2]], [[B_2]] 97; CHECK-NEXT: [[MUL_2:%.*]] = mul i32 [[R_2]], 2 98; CHECK-NEXT: [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2 99; CHECK-NEXT: store i32 [[MUL_2]], i32* [[DST_GEP_2]], align 4 100; CHECK-NEXT: [[A_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[A]], i64 3 101; CHECK-NEXT: [[A_3:%.*]] = load i32, i32* [[A_GEP_3]], align 4 102; CHECK-NEXT: [[B_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 3 103; CHECK-NEXT: [[B_3:%.*]] = load i32, i32* [[B_GEP_3]], align 4 104; CHECK-NEXT: [[R_3:%.*]] = add i32 [[A_3]], [[B_3]] 105; CHECK-NEXT: [[MUL_3:%.*]] = mul i32 [[R_3]], 2 106; CHECK-NEXT: [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3 107; CHECK-NEXT: store i32 [[MUL_3]], i32* [[DST_GEP_3]], align 4 108; CHECK-NEXT: ret void 109; 110entry: 111 %A.0 = load i32, i32* %A, align 4 112 %B.0 = load i32, i32* %B, align 4 113 %r.0 = add i32 %A.0, %B.0 114 %mul.0 = mul i32 %r.0, 2 115 store i32 %mul.0, i32* %dst, align 4 116 %A.gep.1 = getelementptr inbounds i32, i32* %A, i64 1 117 %A.1 = load i32, i32* %A.gep.1, align 4 118 %B.gep.1 = getelementptr inbounds i32, i32* %B, i64 1 119 %B.1 = load i32, i32* %B.gep.1, align 4 120 %r.1 = add i32 %A.1, %B.1 121 %mul.1 = mul i32 %r.1, 2 122 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 123 store i32 %mul.1, i32* %dst.gep.1, align 4 124 %A.gep.2 = getelementptr inbounds i32, i32* %A, i64 2 125 %A.2 = load i32, i32* %A.gep.2, align 4 126 %B.gep.2 = getelementptr inbounds i32, i32* %B, i64 2 127 %B.2 = load i32, i32* %B.gep.2, align 4 128 %r.2 = add i32 %A.2, %B.2 129 %mul.2 = mul i32 %r.2, 2 130 %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2 131 store i32 %mul.2, i32* %dst.gep.2, align 4 132 %A.gep.3 = getelementptr inbounds i32, i32* %A, i64 3 133 %A.3 = load i32, i32* %A.gep.3, align 4 134 %B.gep.3 = getelementptr inbounds i32, i32* %B, i64 3 135 %B.3 = load i32, i32* %B.gep.3, align 4 136 %r.3 = add i32 %A.3, %B.3 137 %mul.3 = mul i32 %r.3, 2 138 %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3 139 store i32 %mul.3, i32* %dst.gep.3, align 4 140 141 ret void 142} 143 144declare void @use(i32) 145 146declare void @bar() 147 148define void @needs_versioning_profitable_split_points(i32* %dst, i32* %src) { 149; CHECK-LABEL: @needs_versioning_profitable_split_points( 150; CHECK-NEXT: entry: 151; CHECK-NEXT: call void @bar() 152; CHECK-NEXT: call void @bar() 153; CHECK-NEXT: call void @bar() 154; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 155; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 156; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 157; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 158; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 159; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 160; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 161; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 162; CHECK-NEXT: [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 163; CHECK-NEXT: [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4 164; CHECK-NEXT: [[R_2:%.*]] = ashr i32 [[SRC_2]], 16 165; CHECK-NEXT: [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2 166; CHECK-NEXT: store i32 [[R_2]], i32* [[DST_GEP_2]], align 4 167; CHECK-NEXT: [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 168; CHECK-NEXT: [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4 169; CHECK-NEXT: [[R_3:%.*]] = ashr i32 [[SRC_3]], 16 170; CHECK-NEXT: [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3 171; CHECK-NEXT: store i32 [[R_3]], i32* [[DST_GEP_3]], align 4 172; CHECK-NEXT: call void @bar() 173; CHECK-NEXT: ret void 174; 175entry: 176 call void @bar() 177 call void @bar() 178 call void @bar() 179 180 %src.0 = load i32, i32* %src, align 4 181 %r.0 = ashr i32 %src.0, 16 182 store i32 %r.0, i32* %dst, align 4 183 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 184 %src.1 = load i32, i32* %src.gep.1, align 4 185 %r.1 = ashr i32 %src.1, 16 186 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 187 store i32 %r.1, i32* %dst.gep.1, align 4 188 %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2 189 %src.2 = load i32, i32* %src.gep.2, align 4 190 %r.2 = ashr i32 %src.2, 16 191 %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2 192 store i32 %r.2, i32* %dst.gep.2, align 4 193 %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3 194 %src.3 = load i32, i32* %src.gep.3, align 4 195 %r.3 = ashr i32 %src.3, 16 196 %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3 197 store i32 %r.3, i32* %dst.gep.3, align 4 198 199 call void @bar() 200 ret void 201} 202 203define void @needs_versioning_profitable_load_used_outside_region1(i32* %dst, i32* %src, i1 %c) { 204; CHECK-LABEL: @needs_versioning_profitable_load_used_outside_region1( 205; CHECK-NEXT: entry: 206; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 207; CHECK: then: 208; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 209; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 210; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 211; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 212; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 213; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 214; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 215; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 216; CHECK-NEXT: [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 217; CHECK-NEXT: [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4 218; CHECK-NEXT: [[R_2:%.*]] = ashr i32 [[SRC_2]], 16 219; CHECK-NEXT: [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2 220; CHECK-NEXT: store i32 [[R_2]], i32* [[DST_GEP_2]], align 4 221; CHECK-NEXT: [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 222; CHECK-NEXT: [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4 223; CHECK-NEXT: [[R_3:%.*]] = ashr i32 [[SRC_3]], 16 224; CHECK-NEXT: [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3 225; CHECK-NEXT: store i32 [[R_3]], i32* [[DST_GEP_3]], align 4 226; CHECK-NEXT: [[SRC_GEP_5:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 5 227; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[SRC_GEP_5]], align 4 228; CHECK-NEXT: call void @use(i32 [[L]]) 229; CHECK-NEXT: br label [[EXIT]] 230; CHECK: exit: 231; CHECK-NEXT: ret void 232; 233entry: 234 br i1 %c, label %then, label %exit 235 236then: 237 %src.0 = load i32, i32* %src, align 4 238 %r.0 = ashr i32 %src.0, 16 239 store i32 %r.0, i32* %dst, align 4 240 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 241 %src.1 = load i32, i32* %src.gep.1, align 4 242 %r.1 = ashr i32 %src.1, 16 243 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 244 store i32 %r.1, i32* %dst.gep.1, align 4 245 %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2 246 %src.2 = load i32, i32* %src.gep.2, align 4 247 %r.2 = ashr i32 %src.2, 16 248 %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2 249 store i32 %r.2, i32* %dst.gep.2, align 4 250 %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3 251 %src.3 = load i32, i32* %src.gep.3, align 4 252 %r.3 = ashr i32 %src.3, 16 253 %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3 254 store i32 %r.3, i32* %dst.gep.3, align 4 255 %src.gep.5 = getelementptr inbounds i32, i32* %src, i64 5 256 %l = load i32, i32* %src.gep.5 257 call void @use(i32 %l) 258 br label %exit 259 260exit: 261 ret void 262} 263 264define void @needs_versioning_profitable_load_used_outside_region2(i32* %dst, i32* %src, i1 %c) { 265; CHECK-LABEL: @needs_versioning_profitable_load_used_outside_region2( 266; CHECK-NEXT: entry: 267; CHECK-NEXT: br i1 [[C:%.*]], label [[THEN:%.*]], label [[EXIT:%.*]] 268; CHECK: then: 269; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 270; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 271; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 272; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 273; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 274; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 275; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 276; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 277; CHECK-NEXT: [[SRC_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 2 278; CHECK-NEXT: [[SRC_2:%.*]] = load i32, i32* [[SRC_GEP_2]], align 4 279; CHECK-NEXT: [[SRC_GEP_5:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 5 280; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[SRC_GEP_5]], align 4 281; CHECK-NEXT: [[R_2:%.*]] = ashr i32 [[SRC_2]], 16 282; CHECK-NEXT: [[DST_GEP_2:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 2 283; CHECK-NEXT: store i32 [[R_2]], i32* [[DST_GEP_2]], align 4 284; CHECK-NEXT: [[SRC_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 3 285; CHECK-NEXT: [[SRC_3:%.*]] = load i32, i32* [[SRC_GEP_3]], align 4 286; CHECK-NEXT: [[R_3:%.*]] = ashr i32 [[SRC_3]], 16 287; CHECK-NEXT: [[DST_GEP_3:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 3 288; CHECK-NEXT: store i32 [[R_3]], i32* [[DST_GEP_3]], align 4 289; CHECK-NEXT: call void @use(i32 [[L]]) 290; CHECK-NEXT: br label [[EXIT]] 291; CHECK: exit: 292; CHECK-NEXT: ret void 293; 294entry: 295 br i1 %c, label %then, label %exit 296 297then: 298 %src.0 = load i32, i32* %src, align 4 299 %r.0 = ashr i32 %src.0, 16 300 store i32 %r.0, i32* %dst, align 4 301 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 302 %src.1 = load i32, i32* %src.gep.1, align 4 303 %r.1 = ashr i32 %src.1, 16 304 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 305 store i32 %r.1, i32* %dst.gep.1, align 4 306 %src.gep.2 = getelementptr inbounds i32, i32* %src, i64 2 307 %src.2 = load i32, i32* %src.gep.2, align 4 308 %src.gep.5 = getelementptr inbounds i32, i32* %src, i64 5 309 %l = load i32, i32* %src.gep.5 310 %r.2 = ashr i32 %src.2, 16 311 %dst.gep.2 = getelementptr inbounds i32, i32* %dst, i64 2 312 store i32 %r.2, i32* %dst.gep.2, align 4 313 %src.gep.3 = getelementptr inbounds i32, i32* %src, i64 3 314 %src.3 = load i32, i32* %src.gep.3, align 4 315 %r.3 = ashr i32 %src.3, 16 316 %dst.gep.3 = getelementptr inbounds i32, i32* %dst, i64 3 317 store i32 %r.3, i32* %dst.gep.3, align 4 318 call void @use(i32 %l) 319 br label %exit 320 321exit: 322 ret void 323} 324 325define void @no_version(i32* nocapture %dst, i32* nocapture readonly %src) { 326; CHECK-LABEL: @no_version( 327; CHECK-NEXT: entry: 328; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC:%.*]], i64 1 329; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[SRC]] to <2 x i32>* 330; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i32>, <2 x i32>* [[TMP0]], align 4 331; CHECK-NEXT: [[TMP2:%.*]] = ashr <2 x i32> [[TMP1]], <i32 16, i32 16> 332; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST:%.*]], i64 1 333; CHECK-NEXT: [[TMP3:%.*]] = bitcast i32* [[DST]] to <2 x i32>* 334; CHECK-NEXT: store <2 x i32> [[TMP2]], <2 x i32>* [[TMP3]], align 4 335; CHECK-NEXT: ret void 336; 337entry: 338 %src.0 = load i32, i32* %src, align 4 339 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 340 %src.1 = load i32, i32* %src.gep.1, align 4 341 %r.0 = ashr i32 %src.0, 16 342 %r.1 = ashr i32 %src.1, 16 343 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 344 store i32 %r.0, i32* %dst, align 4 345 store i32 %r.1, i32* %dst.gep.1, align 4 346 ret void 347} 348 349define void @version_multiple(i32* nocapture %out_block, i32* nocapture readonly %counter) { 350; CHECK-LABEL: @version_multiple( 351; CHECK-NEXT: entry: 352; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[COUNTER:%.*]], align 4 353; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[OUT_BLOCK:%.*]], align 4 354; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[TMP1]], [[TMP0]] 355; CHECK-NEXT: store i32 [[XOR]], i32* [[OUT_BLOCK]], align 4 356; CHECK-NEXT: [[ARRAYIDX_1:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 1 357; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX_1]], align 4 358; CHECK-NEXT: [[ARRAYIDX2_1:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 1 359; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[ARRAYIDX2_1]], align 4 360; CHECK-NEXT: [[XOR_1:%.*]] = xor i32 [[TMP3]], [[TMP2]] 361; CHECK-NEXT: store i32 [[XOR_1]], i32* [[ARRAYIDX2_1]], align 4 362; CHECK-NEXT: [[ARRAYIDX_2:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 2 363; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[ARRAYIDX_2]], align 4 364; CHECK-NEXT: [[ARRAYIDX2_2:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 2 365; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[ARRAYIDX2_2]], align 4 366; CHECK-NEXT: [[XOR_2:%.*]] = xor i32 [[TMP5]], [[TMP4]] 367; CHECK-NEXT: store i32 [[XOR_2]], i32* [[ARRAYIDX2_2]], align 4 368; CHECK-NEXT: [[ARRAYIDX_3:%.*]] = getelementptr inbounds i32, i32* [[COUNTER]], i64 3 369; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[ARRAYIDX_3]], align 4 370; CHECK-NEXT: [[ARRAYIDX2_3:%.*]] = getelementptr inbounds i32, i32* [[OUT_BLOCK]], i64 3 371; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[ARRAYIDX2_3]], align 4 372; CHECK-NEXT: [[XOR_3:%.*]] = xor i32 [[TMP7]], [[TMP6]] 373; CHECK-NEXT: store i32 [[XOR_3]], i32* [[ARRAYIDX2_3]], align 4 374; CHECK-NEXT: ret void 375; 376entry: 377 %0 = load i32, i32* %counter, align 4 378 %1 = load i32, i32* %out_block, align 4 379 %xor = xor i32 %1, %0 380 store i32 %xor, i32* %out_block, align 4 381 %arrayidx.1 = getelementptr inbounds i32, i32* %counter, i64 1 382 %2 = load i32, i32* %arrayidx.1, align 4 383 %arrayidx2.1 = getelementptr inbounds i32, i32* %out_block, i64 1 384 %3 = load i32, i32* %arrayidx2.1, align 4 385 %xor.1 = xor i32 %3, %2 386 store i32 %xor.1, i32* %arrayidx2.1, align 4 387 %arrayidx.2 = getelementptr inbounds i32, i32* %counter, i64 2 388 %4 = load i32, i32* %arrayidx.2, align 4 389 %arrayidx2.2 = getelementptr inbounds i32, i32* %out_block, i64 2 390 %5 = load i32, i32* %arrayidx2.2, align 4 391 %xor.2 = xor i32 %5, %4 392 store i32 %xor.2, i32* %arrayidx2.2, align 4 393 %arrayidx.3 = getelementptr inbounds i32, i32* %counter, i64 3 394 %6 = load i32, i32* %arrayidx.3, align 4 395 %arrayidx2.3 = getelementptr inbounds i32, i32* %out_block, i64 3 396 %7 = load i32, i32* %arrayidx2.3, align 4 397 %xor.3 = xor i32 %7, %6 398 store i32 %xor.3, i32* %arrayidx2.3, align 4 399 ret void 400} 401 402define i32 @use_outside_version_bb(i32* %dst, i32* %src, i1 %c.1) { 403; CHECK-LABEL: @use_outside_version_bb( 404; CHECK-NEXT: entry: 405; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 406; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 407; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 408; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 409; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 410; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 411; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 412; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 413; CHECK-NEXT: br label [[EXIT:%.*]] 414; CHECK: exit: 415; CHECK-NEXT: ret i32 [[R_0]] 416; 417entry: 418 %src.0 = load i32, i32* %src, align 4 419 %r.0 = ashr i32 %src.0, 16 420 store i32 %r.0, i32* %dst, align 4 421 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 422 %src.1 = load i32, i32* %src.gep.1, align 4 423 %r.1 = ashr i32 %src.1, 16 424 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 425 store i32 %r.1, i32* %dst.gep.1, align 4 426 br label %exit 427 428exit: 429 ret i32 %r.0 430} 431 432define i32 @value_used_in_return(i32* %dst, i32* %src, i32 %x) { 433; CHECK-LABEL: @value_used_in_return( 434; CHECK-NEXT: entry: 435; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 436; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 437; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 438; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 439; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 440; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 441; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 442; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 443; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 20 444; CHECK-NEXT: ret i32 [[ADD]] 445; 446entry: 447 %src.0 = load i32, i32* %src, align 4 448 %r.0 = ashr i32 %src.0, 16 449 store i32 %r.0, i32* %dst, align 4 450 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 451 %src.1 = load i32, i32* %src.gep.1, align 4 452 %r.1 = ashr i32 %src.1, 16 453 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 454 store i32 %r.1, i32* %dst.gep.1, align 4 455 %add = add i32 %x, 20 456 ret i32 %add 457} 458define i32 @needs_versioning2_cond_br(i32* %dst, i32* %src, i1 %c.1) { 459; CHECK-LABEL: @needs_versioning2_cond_br( 460; CHECK-NEXT: entry: 461; CHECK-NEXT: br i1 [[C_1:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] 462; CHECK: then: 463; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC:%.*]], align 4 464; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 465; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 466; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 467; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 468; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 469; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 470; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 471; CHECK-NEXT: ret i32 10 472; CHECK: else: 473; CHECK-NEXT: ret i32 0 474; 475entry: 476 br i1 %c.1, label %then, label %else 477 478then: 479 %src.0 = load i32, i32* %src, align 4 480 %r.0 = ashr i32 %src.0, 16 481 store i32 %r.0, i32* %dst, align 4 482 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 483 %src.1 = load i32, i32* %src.gep.1, align 4 484 %r.1 = ashr i32 %src.1, 16 485 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 486 store i32 %r.1, i32* %dst.gep.1, align 4 487 ret i32 10 488 489 490else: 491 ret i32 0 492} 493 494define void @pointer_defined_in_bb(i32* %dst, i32** %src.p) { 495; CHECK-LABEL: @pointer_defined_in_bb( 496; CHECK-NEXT: entry: 497; CHECK-NEXT: [[SRC:%.*]] = load i32*, i32** [[SRC_P:%.*]], align 8 498; CHECK-NEXT: [[SRC_0:%.*]] = load i32, i32* [[SRC]], align 4 499; CHECK-NEXT: [[R_0:%.*]] = ashr i32 [[SRC_0]], 16 500; CHECK-NEXT: store i32 [[R_0]], i32* [[DST:%.*]], align 4 501; CHECK-NEXT: [[SRC_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[SRC]], i64 1 502; CHECK-NEXT: [[SRC_1:%.*]] = load i32, i32* [[SRC_GEP_1]], align 4 503; CHECK-NEXT: [[R_1:%.*]] = ashr i32 [[SRC_1]], 16 504; CHECK-NEXT: [[DST_GEP_1:%.*]] = getelementptr inbounds i32, i32* [[DST]], i64 1 505; CHECK-NEXT: store i32 [[R_1]], i32* [[DST_GEP_1]], align 4 506; CHECK-NEXT: ret void 507; 508entry: 509 %src = load i32*, i32** %src.p 510 %src.0 = load i32, i32* %src, align 4 511 %r.0 = ashr i32 %src.0, 16 512 store i32 %r.0, i32* %dst, align 4 513 %src.gep.1 = getelementptr inbounds i32, i32* %src, i64 1 514 %src.1 = load i32, i32* %src.gep.1, align 4 515 %r.1 = ashr i32 %src.1, 16 516 %dst.gep.1 = getelementptr inbounds i32, i32* %dst, i64 1 517 store i32 %r.1, i32* %dst.gep.1, align 4 518 ret void 519} 520 521define void @clobber_same_underlying_object(i32* %this) { 522; CHECK-LABEL: @clobber_same_underlying_object( 523; CHECK-NEXT: entry: 524; CHECK-NEXT: [[P_3:%.*]] = getelementptr inbounds i32, i32* [[THIS:%.*]], i32 3 525; CHECK-NEXT: store i32 10, i32* [[P_3]], align 8 526; CHECK-NEXT: tail call void @clobber() 527; CHECK-NEXT: [[P_4:%.*]] = getelementptr inbounds i32, i32* [[THIS]], i32 4 528; CHECK-NEXT: [[L2:%.*]] = load i32, i32* [[P_4]], align 8 529; CHECK-NEXT: store i32 20, i32* [[P_4]], align 8 530; CHECK-NEXT: ret void 531; 532entry: 533 %p.3 = getelementptr inbounds i32, i32* %this, i32 3 534 store i32 10, i32* %p.3, align 8 535 tail call void @clobber() 536 %p.4 = getelementptr inbounds i32, i32* %this, i32 4 537 %l2 = load i32, i32* %p.4, align 8 538 store i32 20, i32* %p.4, align 8 539 ret void 540} 541 542declare void @clobber() 543 544define void @slp_not_beneficial(i32* %A, i32* %B) { 545; CHECK-LABEL: @slp_not_beneficial( 546; CHECK-NEXT: bb: 547; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 4 548; CHECK-NEXT: store i32 0, i32* [[TMP]], align 8 549; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 5 550; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, i32* [[B:%.*]], i32 4 551; CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP4]], align 8 552; CHECK-NEXT: store i32 [[TMP5]], i32* [[TMP3]], align 8 553; CHECK-NEXT: ret void 554; 555bb: 556 %tmp = getelementptr inbounds i32, i32* %A, i32 4 557 store i32 0, i32* %tmp, align 8 558 %tmp3 = getelementptr inbounds i32, i32* %A, i32 5 559 %tmp4 = getelementptr inbounds i32, i32* %B, i32 4 560 %tmp5 = load i32, i32* %tmp4, align 8 561 store i32 %tmp5, i32* %tmp3, align 8 562 ret void 563} 564 565define void @widget(double* %ptr, double* %ptr.2) { 566; CHECK-LABEL: @widget( 567; CHECK-NEXT: bb1: 568; CHECK-NEXT: [[TMP3:%.*]] = load double, double* null, align 8 569; CHECK-NEXT: [[TMP4:%.*]] = fmul double undef, [[TMP3]] 570; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds double, double* [[PTR:%.*]], i32 0 571; CHECK-NEXT: [[TMP6:%.*]] = load double, double* [[TMP5]], align 8 572; CHECK-NEXT: [[TMP7:%.*]] = fadd double [[TMP6]], [[TMP4]] 573; CHECK-NEXT: store double [[TMP7]], double* [[TMP5]], align 8 574; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds double, double* [[PTR_2:%.*]], i64 0 575; CHECK-NEXT: [[TMP9:%.*]] = load double, double* [[TMP8]], align 8 576; CHECK-NEXT: [[TMP10:%.*]] = fmul double undef, [[TMP9]] 577; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds double, double* [[PTR]], i32 1 578; CHECK-NEXT: [[TMP12:%.*]] = load double, double* [[TMP11]], align 8 579; CHECK-NEXT: [[TMP13:%.*]] = fadd double [[TMP12]], [[TMP10]] 580; CHECK-NEXT: store double [[TMP13]], double* [[TMP11]], align 8 581; CHECK-NEXT: br label [[BB15:%.*]] 582; CHECK: bb15: 583; CHECK-NEXT: br label [[BB15]] 584; 585bb1: ; preds = %bb 586 %tmp3 = load double, double* null, align 8 587 %tmp4 = fmul double undef, %tmp3 588 %tmp5 = getelementptr inbounds double, double* %ptr, i32 0 589 %tmp6 = load double, double* %tmp5, align 8 590 %tmp7 = fadd double %tmp6, %tmp4 591 store double %tmp7, double* %tmp5, align 8 592 %tmp8 = getelementptr inbounds double, double* %ptr.2, i64 0 593 %tmp9 = load double, double* %tmp8, align 8 594 %tmp10 = fmul double undef, %tmp9 595 %tmp11 = getelementptr inbounds double, double* %ptr, i32 1 596 %tmp12 = load double, double* %tmp11, align 8 597 %tmp13 = fadd double %tmp12, %tmp10 598 store double %tmp13, double* %tmp11, align 8 599 br label %bb15 600 601bb15: ; preds = %bb15, %bb14 602 br label %bb15 603} 604 605%struct = type { i32, i32, float, float } 606 607; Some points we collected as candidates for runtime checks have been removed 608; before generating runtime checks. Make sure versioning is skipped. 609define void @test_bounds_removed_before_runtime_checks(%struct * %A, i32** %B, i1 %c) { 610; CHECK-LABEL: @test_bounds_removed_before_runtime_checks( 611; CHECK-NEXT: entry: 612; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds [[STRUCT:%.*]], %struct* [[A:%.*]], i64 0, i32 0 613; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 1 614; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[TMP11]] to <2 x i32>* 615; CHECK-NEXT: store <2 x i32> <i32 10, i32 300>, <2 x i32>* [[TMP0]], align 8 616; CHECK-NEXT: [[TMP13:%.*]] = load i32*, i32** [[B:%.*]], align 8 617; CHECK-NEXT: br i1 [[C:%.*]], label [[BB23:%.*]], label [[BB14:%.*]] 618; CHECK: bb14: 619; CHECK-NEXT: [[TMP15:%.*]] = sext i32 10 to i64 620; CHECK-NEXT: [[TMP16:%.*]] = add nsw i64 2, [[TMP15]] 621; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, i32* [[TMP13]], i64 [[TMP16]] 622; CHECK-NEXT: [[TMP18:%.*]] = bitcast i32* [[TMP17]] to i8* 623; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i8, i8* [[TMP18]], i64 3 624; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 2 625; CHECK-NEXT: store float 0.000000e+00, float* [[TMP20]], align 8 626; CHECK-NEXT: [[TMP21:%.*]] = load i8, i8* [[TMP19]], align 1 627; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT]], %struct* [[A]], i64 0, i32 3 628; CHECK-NEXT: store float 0.000000e+00, float* [[TMP22]], align 4 629; CHECK-NEXT: br label [[BB23]] 630; CHECK: bb23: 631; CHECK-NEXT: ret void 632; 633entry: 634 %tmp1 = fmul float 10.0, 20.0 635 %tmp2 = fptosi float %tmp1 to i32 636 %tmp3 = fmul float 30.0, 20.0 637 %tmp4 = fptosi float %tmp3 to i32 638 %tmp5 = icmp sgt i32 100, %tmp2 639 %tmp6 = select i1 %tmp5, i32 %tmp2, i32 10 640 %tmp7 = select i1 false, i32 0, i32 %tmp6 641 %tmp8 = icmp sgt i32 200, %tmp4 642 %tmp9 = select i1 %tmp8, i32 %tmp4, i32 300 643 %tmp10 = select i1 false, i32 0, i32 %tmp9 644 %tmp11 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 0 645 store i32 %tmp7, i32* %tmp11, align 8 646 %tmp12 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 1 647 store i32 %tmp10, i32* %tmp12, align 4 648 %tmp13 = load i32*, i32** %B, align 8 649 br i1 %c, label %bb23, label %bb14 650 651bb14: 652 %tmp15 = sext i32 %tmp7 to i64 653 %tmp16 = add nsw i64 2, %tmp15 654 %tmp17 = getelementptr inbounds i32, i32* %tmp13, i64 %tmp16 655 %tmp18 = bitcast i32* %tmp17 to i8* 656 %tmp19 = getelementptr inbounds i8, i8* %tmp18, i64 3 657 %tmp20 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 2 658 store float 0.0, float* %tmp20, align 8 659 %tmp21 = load i8, i8* %tmp19, align 1 660 %tmp22 = getelementptr inbounds %struct, %struct* %A, i64 0, i32 3 661 store float 0.0, float* %tmp22, align 4 662 br label %bb23 663 664bb23: 665 ret void 666} 667 668; In this test there's a single bound, do not generate runtime checks. 669define void @single_membound(double* %arg, double* %arg1, double %x) { 670; CHECK-LABEL: @single_membound( 671; CHECK-NEXT: entry: 672; CHECK-NEXT: [[TMP:%.*]] = fsub double [[X:%.*]], 9.900000e+01 673; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds double, double* [[ARG:%.*]], i64 1 674; CHECK-NEXT: store double [[TMP]], double* [[TMP9]], align 8 675; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds double, double* [[ARG1:%.*]], i64 0 676; CHECK-NEXT: [[TMP12:%.*]] = load double, double* [[TMP10]], align 8 677; CHECK-NEXT: [[TMP13:%.*]] = fsub double 1.000000e+00, [[TMP12]] 678; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds double, double* [[ARG]], i64 2 679; CHECK-NEXT: br label [[BB15:%.*]] 680; CHECK: bb15: 681; CHECK-NEXT: [[TMP16:%.*]] = fmul double [[TMP]], 2.000000e+01 682; CHECK-NEXT: store double [[TMP16]], double* [[TMP9]], align 8 683; CHECK-NEXT: [[TMP17:%.*]] = fmul double [[TMP13]], 3.000000e+01 684; CHECK-NEXT: store double [[TMP17]], double* [[TMP14]], align 8 685; CHECK-NEXT: ret void 686; 687entry: 688 %tmp = fsub double %x, 99.0 689 %tmp9 = getelementptr inbounds double, double* %arg, i64 1 690 store double %tmp, double* %tmp9, align 8 691 %tmp10 = getelementptr inbounds double, double* %arg1, i64 0 692 %tmp12 = load double, double* %tmp10, align 8 693 %tmp13 = fsub double 1.0, %tmp12 694 %tmp14 = getelementptr inbounds double, double* %arg, i64 2 695 br label %bb15 696 697bb15: 698 %tmp16 = fmul double %tmp, 20.0 699 store double %tmp16, double* %tmp9, align 8 700 %tmp17 = fmul double %tmp13, 30.0 701 store double %tmp17, double* %tmp14, align 8 702 ret void 703} 704 705%struct.2 = type { [4 x float] } 706 707; Make sure we do not crash when we encounter a SCEVCouldNotCompute. 708define void @no_lcssa_phi(%struct.2* %A, float* %B, i1 %c) { 709; CHECK-LABEL: @no_lcssa_phi( 710; CHECK-NEXT: bb: 711; CHECK-NEXT: br label [[LOOP:%.*]] 712; CHECK: loop: 713; CHECK-NEXT: [[PTR_PHI:%.*]] = phi %struct.2* [ [[A:%.*]], [[BB:%.*]] ], [ null, [[LOOP]] ] 714; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]] 715; CHECK: exit: 716; CHECK-NEXT: [[B_GEP_0:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 0 717; CHECK-NEXT: [[L_0:%.*]] = load float, float* [[B_GEP_0]], align 8 718; CHECK-NEXT: [[ADD_0:%.*]] = fadd float [[L_0]], 1.000000e+01 719; CHECK-NEXT: [[MUL_0:%.*]] = fmul float [[ADD_0]], 3.000000e+01 720; CHECK-NEXT: [[A_GEP_0:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 0 721; CHECK-NEXT: store float [[MUL_0]], float* [[A_GEP_0]], align 8 722; CHECK-NEXT: [[B_GEP_1:%.*]] = getelementptr inbounds float, float* [[B]], i64 1 723; CHECK-NEXT: [[L_1:%.*]] = load float, float* [[B_GEP_1]], align 8 724; CHECK-NEXT: [[ADD_1:%.*]] = fadd float [[L_1]], 1.000000e+01 725; CHECK-NEXT: [[MUL_1:%.*]] = fmul float [[ADD_1]], 3.000000e+01 726; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 1 727; CHECK-NEXT: store float [[MUL_1]], float* [[A_GEP_1]], align 8 728; CHECK-NEXT: [[B_GEP_2:%.*]] = getelementptr inbounds float, float* [[B]], i64 2 729; CHECK-NEXT: [[L_2:%.*]] = load float, float* [[B_GEP_2]], align 8 730; CHECK-NEXT: [[ADD_2:%.*]] = fadd float [[L_2]], 1.000000e+01 731; CHECK-NEXT: [[MUL_2:%.*]] = fmul float [[ADD_2]], 3.000000e+01 732; CHECK-NEXT: [[A_GEP_2:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 2 733; CHECK-NEXT: store float [[MUL_2]], float* [[A_GEP_2]], align 8 734; CHECK-NEXT: [[B_GEP_3:%.*]] = getelementptr inbounds float, float* [[B]], i64 3 735; CHECK-NEXT: [[L_3:%.*]] = load float, float* [[B_GEP_3]], align 8 736; CHECK-NEXT: [[ADD_3:%.*]] = fadd float [[L_3]], 1.000000e+01 737; CHECK-NEXT: [[MUL_3:%.*]] = fmul float [[ADD_3]], 3.000000e+01 738; CHECK-NEXT: [[A_GEP_3:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI]], i64 0, i32 0, i32 3 739; CHECK-NEXT: store float [[MUL_3]], float* [[A_GEP_3]], align 8 740; CHECK-NEXT: ret void 741; 742bb: 743 br label %loop 744 745loop: 746 %ptr.phi = phi %struct.2* [ %A, %bb ], [ null, %loop ] 747 br i1 %c, label %exit, label %loop 748 749exit: 750 %B.gep.0 = getelementptr inbounds float, float* %B, i64 0 751 %l.0 = load float, float* %B.gep.0, align 8 752 %add.0 = fadd float %l.0, 10.0 753 %mul.0 = fmul float %add.0, 30.0 754 %A.gep.0 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 0 755 store float %mul.0, float* %A.gep.0, align 8 756 %B.gep.1 = getelementptr inbounds float, float* %B, i64 1 757 %l.1 = load float, float* %B.gep.1, align 8 758 %add.1 = fadd float %l.1, 10.0 759 %mul.1 = fmul float %add.1, 30.0 760 %A.gep.1 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 1 761 store float %mul.1, float* %A.gep.1, align 8 762 %B.gep.2 = getelementptr inbounds float, float* %B, i64 2 763 %l.2 = load float, float* %B.gep.2, align 8 764 %add.2 = fadd float %l.2, 10.0 765 %mul.2 = fmul float %add.2, 30.0 766 %A.gep.2 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 2 767 store float %mul.2, float* %A.gep.2, align 8 768 %B.gep.3 = getelementptr inbounds float, float* %B, i64 3 769 %l.3 = load float, float* %B.gep.3, align 8 770 %add.3 = fadd float %l.3, 10.0 771 %mul.3 = fmul float %add.3, 30.0 772 %A.gep.3 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi, i64 0, i32 0, i32 3 773 store float %mul.3, float* %A.gep.3, align 8 774 ret void 775} 776 777; Make sure lcssa phis as pointer bases are handled properly. 778define void @lcssa_phi(%struct.2* %A, float* %B, i1 %c) { 779; CHECK-LABEL: @lcssa_phi( 780; CHECK-NEXT: bb: 781; CHECK-NEXT: br label [[LOOP:%.*]] 782; CHECK: loop: 783; CHECK-NEXT: [[PTR_PHI:%.*]] = phi %struct.2* [ [[A:%.*]], [[BB:%.*]] ], [ null, [[LOOP]] ] 784; CHECK-NEXT: br i1 [[C:%.*]], label [[EXIT:%.*]], label [[LOOP]] 785; CHECK: exit: 786; CHECK-NEXT: [[PTR_PHI_LCSSA:%.*]] = phi %struct.2* [ [[PTR_PHI]], [[LOOP]] ] 787; CHECK-NEXT: [[B_GEP_0:%.*]] = getelementptr inbounds float, float* [[B:%.*]], i64 0 788; CHECK-NEXT: [[L_0:%.*]] = load float, float* [[B_GEP_0]], align 8 789; CHECK-NEXT: [[ADD_0:%.*]] = fadd float [[L_0]], 1.000000e+01 790; CHECK-NEXT: [[MUL_0:%.*]] = fmul float [[ADD_0]], 3.000000e+01 791; CHECK-NEXT: [[A_GEP_0:%.*]] = getelementptr inbounds [[STRUCT_2:%.*]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 0 792; CHECK-NEXT: store float [[MUL_0]], float* [[A_GEP_0]], align 8 793; CHECK-NEXT: [[B_GEP_1:%.*]] = getelementptr inbounds float, float* [[B]], i64 1 794; CHECK-NEXT: [[L_1:%.*]] = load float, float* [[B_GEP_1]], align 8 795; CHECK-NEXT: [[ADD_1:%.*]] = fadd float [[L_1]], 1.000000e+01 796; CHECK-NEXT: [[MUL_1:%.*]] = fmul float [[ADD_1]], 3.000000e+01 797; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 1 798; CHECK-NEXT: store float [[MUL_1]], float* [[A_GEP_1]], align 8 799; CHECK-NEXT: [[B_GEP_2:%.*]] = getelementptr inbounds float, float* [[B]], i64 2 800; CHECK-NEXT: [[L_2:%.*]] = load float, float* [[B_GEP_2]], align 8 801; CHECK-NEXT: [[ADD_2:%.*]] = fadd float [[L_2]], 1.000000e+01 802; CHECK-NEXT: [[MUL_2:%.*]] = fmul float [[ADD_2]], 3.000000e+01 803; CHECK-NEXT: [[A_GEP_2:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 2 804; CHECK-NEXT: store float [[MUL_2]], float* [[A_GEP_2]], align 8 805; CHECK-NEXT: [[B_GEP_3:%.*]] = getelementptr inbounds float, float* [[B]], i64 3 806; CHECK-NEXT: [[L_3:%.*]] = load float, float* [[B_GEP_3]], align 8 807; CHECK-NEXT: [[ADD_3:%.*]] = fadd float [[L_3]], 1.000000e+01 808; CHECK-NEXT: [[MUL_3:%.*]] = fmul float [[ADD_3]], 3.000000e+01 809; CHECK-NEXT: [[A_GEP_3:%.*]] = getelementptr inbounds [[STRUCT_2]], %struct.2* [[PTR_PHI_LCSSA]], i64 0, i32 0, i32 3 810; CHECK-NEXT: store float [[MUL_3]], float* [[A_GEP_3]], align 8 811; CHECK-NEXT: ret void 812; 813bb: 814 br label %loop 815 816loop: 817 %ptr.phi = phi %struct.2* [ %A, %bb ], [ null, %loop ] 818 br i1 %c, label %exit, label %loop 819 820exit: 821 %ptr.phi.lcssa = phi %struct.2* [ %ptr.phi, %loop ] 822 %B.gep.0 = getelementptr inbounds float, float* %B, i64 0 823 %l.0 = load float, float* %B.gep.0, align 8 824 %add.0 = fadd float %l.0, 10.0 825 %mul.0 = fmul float %add.0, 30.0 826 %A.gep.0 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 0 827 store float %mul.0, float* %A.gep.0, align 8 828 %B.gep.1 = getelementptr inbounds float, float* %B, i64 1 829 %l.1 = load float, float* %B.gep.1, align 8 830 %add.1 = fadd float %l.1, 10.0 831 %mul.1 = fmul float %add.1, 30.0 832 %A.gep.1 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 1 833 store float %mul.1, float* %A.gep.1, align 8 834 %B.gep.2 = getelementptr inbounds float, float* %B, i64 2 835 %l.2 = load float, float* %B.gep.2, align 8 836 %add.2 = fadd float %l.2, 10.0 837 %mul.2 = fmul float %add.2, 30.0 838 %A.gep.2 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 2 839 store float %mul.2, float* %A.gep.2, align 8 840 %B.gep.3 = getelementptr inbounds float, float* %B, i64 3 841 %l.3 = load float, float* %B.gep.3, align 8 842 %add.3 = fadd float %l.3, 10.0 843 %mul.3 = fmul float %add.3, 30.0 844 %A.gep.3 = getelementptr inbounds %struct.2, %struct.2* %ptr.phi.lcssa, i64 0, i32 0, i32 3 845 store float %mul.3, float* %A.gep.3, align 8 846 ret void 847} 848 849%struct.spam = type { [60 x i32], i32, [12 x i8] } 850 851declare void @foo(i8*) 852 853; Test case with a basic block where parts can be vectorized without versioning. 854define i32 @block_partly_vectorized_without_versioning(%struct.spam* readonly %arg, i8* nocapture readonly %arg1, i8* nocapture %arg2, i8* nocapture readonly %arg3, i8* %A, i8* %B) { 855; CHECK-LABEL: @block_partly_vectorized_without_versioning( 856; CHECK-NEXT: bb: 857; CHECK-NEXT: [[T:%.*]] = alloca <16 x i8>, align 16 858; CHECK-NEXT: [[T4:%.*]] = getelementptr inbounds <16 x i8>, <16 x i8>* [[T]], i64 0, i64 0 859; CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds i8, i8* [[ARG3:%.*]], i64 1 860; CHECK-NEXT: [[T6:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 2 861; CHECK-NEXT: [[T7:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 3 862; CHECK-NEXT: [[T8:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 4 863; CHECK-NEXT: [[T9:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 5 864; CHECK-NEXT: [[T10:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 6 865; CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 7 866; CHECK-NEXT: [[T12:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 8 867; CHECK-NEXT: [[T13:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 9 868; CHECK-NEXT: [[T14:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 10 869; CHECK-NEXT: [[T15:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 11 870; CHECK-NEXT: [[T16:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 12 871; CHECK-NEXT: [[T17:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 13 872; CHECK-NEXT: [[T18:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 14 873; CHECK-NEXT: [[T19:%.*]] = bitcast i8* [[ARG1:%.*]] to <16 x i8>* 874; CHECK-NEXT: [[A_GEP_0:%.*]] = getelementptr i8, i8* [[A:%.*]], i64 0 875; CHECK-NEXT: [[B_GEP_0:%.*]] = getelementptr i8, i8* [[B:%.*]], i64 0 876; CHECK-NEXT: [[A_GEP_1:%.*]] = getelementptr i8, i8* [[A]], i64 1 877; CHECK-NEXT: [[B_GEP_1:%.*]] = getelementptr i8, i8* [[B]], i64 1 878; CHECK-NEXT: [[A_GEP_2:%.*]] = getelementptr i8, i8* [[A]], i64 2 879; CHECK-NEXT: [[B_GEP_2:%.*]] = getelementptr i8, i8* [[B]], i64 2 880; CHECK-NEXT: [[A_GEP_3:%.*]] = getelementptr i8, i8* [[A]], i64 3 881; CHECK-NEXT: [[B_GEP_3:%.*]] = getelementptr i8, i8* [[B]], i64 3 882; CHECK-NEXT: [[A_GEP_4:%.*]] = getelementptr i8, i8* [[A]], i64 4 883; CHECK-NEXT: [[B_GEP_4:%.*]] = getelementptr i8, i8* [[B]], i64 4 884; CHECK-NEXT: [[A_GEP_5:%.*]] = getelementptr i8, i8* [[A]], i64 5 885; CHECK-NEXT: [[B_GEP_5:%.*]] = getelementptr i8, i8* [[B]], i64 5 886; CHECK-NEXT: [[A_GEP_6:%.*]] = getelementptr i8, i8* [[A]], i64 6 887; CHECK-NEXT: [[B_GEP_6:%.*]] = getelementptr i8, i8* [[B]], i64 6 888; CHECK-NEXT: [[A_GEP_7:%.*]] = getelementptr i8, i8* [[A]], i64 7 889; CHECK-NEXT: [[B_GEP_7:%.*]] = getelementptr i8, i8* [[B]], i64 7 890; CHECK-NEXT: [[A_GEP_8:%.*]] = getelementptr i8, i8* [[A]], i64 8 891; CHECK-NEXT: [[B_GEP_8:%.*]] = getelementptr i8, i8* [[B]], i64 8 892; CHECK-NEXT: [[A_GEP_9:%.*]] = getelementptr i8, i8* [[A]], i64 9 893; CHECK-NEXT: [[B_GEP_9:%.*]] = getelementptr i8, i8* [[B]], i64 9 894; CHECK-NEXT: [[A_GEP_10:%.*]] = getelementptr i8, i8* [[A]], i64 10 895; CHECK-NEXT: [[B_GEP_10:%.*]] = getelementptr i8, i8* [[B]], i64 10 896; CHECK-NEXT: [[A_GEP_11:%.*]] = getelementptr i8, i8* [[A]], i64 11 897; CHECK-NEXT: [[B_GEP_11:%.*]] = getelementptr i8, i8* [[B]], i64 11 898; CHECK-NEXT: [[A_GEP_12:%.*]] = getelementptr i8, i8* [[A]], i64 12 899; CHECK-NEXT: [[B_GEP_12:%.*]] = getelementptr i8, i8* [[B]], i64 12 900; CHECK-NEXT: [[A_GEP_13:%.*]] = getelementptr i8, i8* [[A]], i64 13 901; CHECK-NEXT: [[B_GEP_13:%.*]] = getelementptr i8, i8* [[B]], i64 13 902; CHECK-NEXT: [[A_GEP_14:%.*]] = getelementptr i8, i8* [[A]], i64 14 903; CHECK-NEXT: [[B_GEP_14:%.*]] = getelementptr i8, i8* [[B]], i64 14 904; CHECK-NEXT: [[A_GEP_15:%.*]] = getelementptr i8, i8* [[A]], i64 15 905; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8* [[A_GEP_0]] to <16 x i8>* 906; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, <16 x i8>* [[TMP0]], align 1 907; CHECK-NEXT: [[B_GEP_15:%.*]] = getelementptr i8, i8* [[B]], i64 15 908; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[B_GEP_0]] to <16 x i8>* 909; CHECK-NEXT: [[TMP3:%.*]] = load <16 x i8>, <16 x i8>* [[TMP2]], align 1 910; CHECK-NEXT: [[TMP4:%.*]] = xor <16 x i8> [[TMP1]], [[TMP3]] 911; CHECK-NEXT: [[R_GEP_0:%.*]] = getelementptr i8, i8* [[ARG1]], i64 0 912; CHECK-NEXT: [[R_GEP_1:%.*]] = getelementptr i8, i8* [[ARG1]], i64 1 913; CHECK-NEXT: [[R_GEP_2:%.*]] = getelementptr i8, i8* [[ARG1]], i64 2 914; CHECK-NEXT: [[R_GEP_3:%.*]] = getelementptr i8, i8* [[ARG1]], i64 3 915; CHECK-NEXT: [[R_GEP_4:%.*]] = getelementptr i8, i8* [[ARG1]], i64 4 916; CHECK-NEXT: [[R_GEP_5:%.*]] = getelementptr i8, i8* [[ARG1]], i64 5 917; CHECK-NEXT: [[R_GEP_6:%.*]] = getelementptr i8, i8* [[ARG1]], i64 6 918; CHECK-NEXT: [[R_GEP_7:%.*]] = getelementptr i8, i8* [[ARG1]], i64 7 919; CHECK-NEXT: [[R_GEP_8:%.*]] = getelementptr i8, i8* [[ARG1]], i64 8 920; CHECK-NEXT: [[R_GEP_9:%.*]] = getelementptr i8, i8* [[ARG1]], i64 9 921; CHECK-NEXT: [[R_GEP_10:%.*]] = getelementptr i8, i8* [[ARG1]], i64 10 922; CHECK-NEXT: [[R_GEP_11:%.*]] = getelementptr i8, i8* [[ARG1]], i64 11 923; CHECK-NEXT: [[R_GEP_12:%.*]] = getelementptr i8, i8* [[ARG1]], i64 12 924; CHECK-NEXT: [[R_GEP_13:%.*]] = getelementptr i8, i8* [[ARG1]], i64 13 925; CHECK-NEXT: [[R_GEP_14:%.*]] = getelementptr i8, i8* [[ARG1]], i64 14 926; CHECK-NEXT: [[R_GEP_15:%.*]] = getelementptr i8, i8* [[ARG1]], i64 15 927; CHECK-NEXT: [[TMP5:%.*]] = bitcast i8* [[R_GEP_0]] to <16 x i8>* 928; CHECK-NEXT: store <16 x i8> [[TMP4]], <16 x i8>* [[TMP5]], align 1 929; CHECK-NEXT: [[T21:%.*]] = getelementptr inbounds i8, i8* [[ARG3]], i64 15 930; CHECK-NEXT: [[T22:%.*]] = bitcast i8* [[ARG3]] to <16 x i8>* 931; CHECK-NEXT: call void @foo(i8* nonnull [[T4]]) 932; CHECK-NEXT: [[T26:%.*]] = load i8, i8* [[ARG3]], align 1 933; CHECK-NEXT: [[T27:%.*]] = load i8, i8* [[ARG2:%.*]], align 1 934; CHECK-NEXT: [[T28:%.*]] = xor i8 [[T27]], [[T26]] 935; CHECK-NEXT: store i8 [[T28]], i8* [[ARG2]], align 1 936; CHECK-NEXT: [[T29:%.*]] = load i8, i8* [[T5]], align 1 937; CHECK-NEXT: [[T30:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 1 938; CHECK-NEXT: [[T31:%.*]] = load i8, i8* [[T30]], align 1 939; CHECK-NEXT: [[T32:%.*]] = xor i8 [[T31]], [[T29]] 940; CHECK-NEXT: store i8 [[T32]], i8* [[T30]], align 1 941; CHECK-NEXT: [[T33:%.*]] = load i8, i8* [[T6]], align 1 942; CHECK-NEXT: [[T34:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 2 943; CHECK-NEXT: [[T35:%.*]] = load i8, i8* [[T34]], align 1 944; CHECK-NEXT: [[T36:%.*]] = xor i8 [[T35]], [[T33]] 945; CHECK-NEXT: store i8 [[T36]], i8* [[T34]], align 1 946; CHECK-NEXT: [[T37:%.*]] = load i8, i8* [[T7]], align 1 947; CHECK-NEXT: [[T38:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 3 948; CHECK-NEXT: [[T39:%.*]] = load i8, i8* [[T38]], align 1 949; CHECK-NEXT: [[T40:%.*]] = xor i8 [[T39]], [[T37]] 950; CHECK-NEXT: store i8 [[T40]], i8* [[T38]], align 1 951; CHECK-NEXT: [[T41:%.*]] = load i8, i8* [[T8]], align 1 952; CHECK-NEXT: [[T42:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 4 953; CHECK-NEXT: [[T43:%.*]] = load i8, i8* [[T42]], align 1 954; CHECK-NEXT: [[T44:%.*]] = xor i8 [[T43]], [[T41]] 955; CHECK-NEXT: store i8 [[T44]], i8* [[T42]], align 1 956; CHECK-NEXT: [[T45:%.*]] = load i8, i8* [[T9]], align 1 957; CHECK-NEXT: [[T46:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 5 958; CHECK-NEXT: [[T47:%.*]] = load i8, i8* [[T46]], align 1 959; CHECK-NEXT: [[T48:%.*]] = xor i8 [[T47]], [[T45]] 960; CHECK-NEXT: store i8 [[T48]], i8* [[T46]], align 1 961; CHECK-NEXT: [[T49:%.*]] = load i8, i8* [[T10]], align 1 962; CHECK-NEXT: [[T50:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 6 963; CHECK-NEXT: [[T51:%.*]] = load i8, i8* [[T50]], align 1 964; CHECK-NEXT: [[T52:%.*]] = xor i8 [[T51]], [[T49]] 965; CHECK-NEXT: store i8 [[T52]], i8* [[T50]], align 1 966; CHECK-NEXT: [[T53:%.*]] = load i8, i8* [[T11]], align 1 967; CHECK-NEXT: [[T54:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 7 968; CHECK-NEXT: [[T55:%.*]] = load i8, i8* [[T54]], align 1 969; CHECK-NEXT: [[T56:%.*]] = xor i8 [[T55]], [[T53]] 970; CHECK-NEXT: store i8 [[T56]], i8* [[T54]], align 1 971; CHECK-NEXT: [[T57:%.*]] = load i8, i8* [[T12]], align 1 972; CHECK-NEXT: [[T58:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 8 973; CHECK-NEXT: [[T59:%.*]] = load i8, i8* [[T58]], align 1 974; CHECK-NEXT: [[T60:%.*]] = xor i8 [[T59]], [[T57]] 975; CHECK-NEXT: store i8 [[T60]], i8* [[T58]], align 1 976; CHECK-NEXT: [[T61:%.*]] = load i8, i8* [[T13]], align 1 977; CHECK-NEXT: [[T62:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 9 978; CHECK-NEXT: [[T63:%.*]] = load i8, i8* [[T62]], align 1 979; CHECK-NEXT: [[T64:%.*]] = xor i8 [[T63]], [[T61]] 980; CHECK-NEXT: store i8 [[T64]], i8* [[T62]], align 1 981; CHECK-NEXT: [[T65:%.*]] = load i8, i8* [[T14]], align 1 982; CHECK-NEXT: [[T66:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 10 983; CHECK-NEXT: [[T67:%.*]] = load i8, i8* [[T66]], align 1 984; CHECK-NEXT: [[T68:%.*]] = xor i8 [[T67]], [[T65]] 985; CHECK-NEXT: store i8 [[T68]], i8* [[T66]], align 1 986; CHECK-NEXT: [[T69:%.*]] = load i8, i8* [[T15]], align 1 987; CHECK-NEXT: [[T70:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 11 988; CHECK-NEXT: [[T71:%.*]] = load i8, i8* [[T70]], align 1 989; CHECK-NEXT: [[T72:%.*]] = xor i8 [[T71]], [[T69]] 990; CHECK-NEXT: store i8 [[T72]], i8* [[T70]], align 1 991; CHECK-NEXT: [[T73:%.*]] = load i8, i8* [[T16]], align 1 992; CHECK-NEXT: [[T74:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 12 993; CHECK-NEXT: [[T75:%.*]] = load i8, i8* [[T74]], align 1 994; CHECK-NEXT: [[T76:%.*]] = xor i8 [[T75]], [[T73]] 995; CHECK-NEXT: store i8 [[T76]], i8* [[T74]], align 1 996; CHECK-NEXT: [[T77:%.*]] = load i8, i8* [[T17]], align 1 997; CHECK-NEXT: [[T78:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 13 998; CHECK-NEXT: [[T79:%.*]] = load i8, i8* [[T78]], align 1 999; CHECK-NEXT: [[T80:%.*]] = xor i8 [[T79]], [[T77]] 1000; CHECK-NEXT: store i8 [[T80]], i8* [[T78]], align 1 1001; CHECK-NEXT: [[T81:%.*]] = load i8, i8* [[T18]], align 1 1002; CHECK-NEXT: [[T82:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 14 1003; CHECK-NEXT: [[T83:%.*]] = load i8, i8* [[T82]], align 1 1004; CHECK-NEXT: [[T84:%.*]] = xor i8 [[T83]], [[T81]] 1005; CHECK-NEXT: store i8 [[T84]], i8* [[T82]], align 1 1006; CHECK-NEXT: [[T85:%.*]] = load i8, i8* [[T21]], align 1 1007; CHECK-NEXT: [[T86:%.*]] = getelementptr inbounds i8, i8* [[ARG2]], i64 15 1008; CHECK-NEXT: [[T87:%.*]] = load i8, i8* [[T86]], align 1 1009; CHECK-NEXT: [[T88:%.*]] = xor i8 [[T87]], [[T85]] 1010; CHECK-NEXT: store i8 [[T88]], i8* [[T86]], align 1 1011; CHECK-NEXT: ret i32 1 1012; 1013bb: 1014 %t = alloca <16 x i8>, align 16 1015 %t4 = getelementptr inbounds <16 x i8>, <16 x i8>* %t, i64 0, i64 0 1016 %t5 = getelementptr inbounds i8, i8* %arg3, i64 1 1017 %t6 = getelementptr inbounds i8, i8* %arg3, i64 2 1018 %t7 = getelementptr inbounds i8, i8* %arg3, i64 3 1019 %t8 = getelementptr inbounds i8, i8* %arg3, i64 4 1020 %t9 = getelementptr inbounds i8, i8* %arg3, i64 5 1021 %t10 = getelementptr inbounds i8, i8* %arg3, i64 6 1022 %t11 = getelementptr inbounds i8, i8* %arg3, i64 7 1023 %t12 = getelementptr inbounds i8, i8* %arg3, i64 8 1024 %t13 = getelementptr inbounds i8, i8* %arg3, i64 9 1025 %t14 = getelementptr inbounds i8, i8* %arg3, i64 10 1026 %t15 = getelementptr inbounds i8, i8* %arg3, i64 11 1027 %t16 = getelementptr inbounds i8, i8* %arg3, i64 12 1028 %t17 = getelementptr inbounds i8, i8* %arg3, i64 13 1029 %t18 = getelementptr inbounds i8, i8* %arg3, i64 14 1030 %t19 = bitcast i8* %arg1 to <16 x i8>* 1031 %A.gep.0 = getelementptr i8, i8* %A, i64 0 1032 %A.0 = load i8, i8* %A.gep.0 1033 %B.gep.0 = getelementptr i8, i8* %B, i64 0 1034 %B.0 = load i8, i8* %B.gep.0 1035 %xor.0 = xor i8 %A.0, %B.0 1036 %A.gep.1 = getelementptr i8, i8* %A, i64 1 1037 %A.1 = load i8, i8* %A.gep.1 1038 %B.gep.1 = getelementptr i8, i8* %B, i64 1 1039 %B.1 = load i8, i8* %B.gep.1 1040 %xor.1 = xor i8 %A.1, %B.1 1041 %A.gep.2 = getelementptr i8, i8* %A, i64 2 1042 %A.2 = load i8, i8* %A.gep.2 1043 %B.gep.2 = getelementptr i8, i8* %B, i64 2 1044 %B.2 = load i8, i8* %B.gep.2 1045 %xor.2 = xor i8 %A.2, %B.2 1046 %A.gep.3 = getelementptr i8, i8* %A, i64 3 1047 %A.3 = load i8, i8* %A.gep.3 1048 %B.gep.3 = getelementptr i8, i8* %B, i64 3 1049 %B.3 = load i8, i8* %B.gep.3 1050 %xor.3 = xor i8 %A.3, %B.3 1051 %A.gep.4 = getelementptr i8, i8* %A, i64 4 1052 %A.4 = load i8, i8* %A.gep.4 1053 %B.gep.4 = getelementptr i8, i8* %B, i64 4 1054 %B.4 = load i8, i8* %B.gep.4 1055 %xor.4 = xor i8 %A.4, %B.4 1056 %A.gep.5 = getelementptr i8, i8* %A, i64 5 1057 %A.5 = load i8, i8* %A.gep.5 1058 %B.gep.5 = getelementptr i8, i8* %B, i64 5 1059 %B.5 = load i8, i8* %B.gep.5 1060 %xor.5 = xor i8 %A.5, %B.5 1061 %A.gep.6 = getelementptr i8, i8* %A, i64 6 1062 %A.6 = load i8, i8* %A.gep.6 1063 %B.gep.6 = getelementptr i8, i8* %B, i64 6 1064 %B.6 = load i8, i8* %B.gep.6 1065 %xor.6 = xor i8 %A.6, %B.6 1066 %A.gep.7 = getelementptr i8, i8* %A, i64 7 1067 %A.7 = load i8, i8* %A.gep.7 1068 %B.gep.7 = getelementptr i8, i8* %B, i64 7 1069 %B.7 = load i8, i8* %B.gep.7 1070 %xor.7 = xor i8 %A.7, %B.7 1071 %A.gep.8 = getelementptr i8, i8* %A, i64 8 1072 %A.8 = load i8, i8* %A.gep.8 1073 %B.gep.8 = getelementptr i8, i8* %B, i64 8 1074 %B.8 = load i8, i8* %B.gep.8 1075 %xor.8 = xor i8 %A.8, %B.8 1076 %A.gep.9 = getelementptr i8, i8* %A, i64 9 1077 %A.9 = load i8, i8* %A.gep.9 1078 %B.gep.9 = getelementptr i8, i8* %B, i64 9 1079 %B.9 = load i8, i8* %B.gep.9 1080 %xor.9 = xor i8 %A.9, %B.9 1081 %A.gep.10 = getelementptr i8, i8* %A, i64 10 1082 %A.10 = load i8, i8* %A.gep.10 1083 %B.gep.10 = getelementptr i8, i8* %B, i64 10 1084 %B.10 = load i8, i8* %B.gep.10 1085 %xor.10 = xor i8 %A.10, %B.10 1086 %A.gep.11 = getelementptr i8, i8* %A, i64 11 1087 %A.11 = load i8, i8* %A.gep.11 1088 %B.gep.11 = getelementptr i8, i8* %B, i64 11 1089 %B.11 = load i8, i8* %B.gep.11 1090 %xor.11 = xor i8 %A.11, %B.11 1091 %A.gep.12 = getelementptr i8, i8* %A, i64 12 1092 %A.12 = load i8, i8* %A.gep.12 1093 %B.gep.12 = getelementptr i8, i8* %B, i64 12 1094 %B.12 = load i8, i8* %B.gep.12 1095 %xor.12 = xor i8 %A.12, %B.12 1096 %A.gep.13 = getelementptr i8, i8* %A, i64 13 1097 %A.13 = load i8, i8* %A.gep.13 1098 %B.gep.13 = getelementptr i8, i8* %B, i64 13 1099 %B.13 = load i8, i8* %B.gep.13 1100 %xor.13 = xor i8 %A.13, %B.13 1101 %A.gep.14 = getelementptr i8, i8* %A, i64 14 1102 %A.14 = load i8, i8* %A.gep.14 1103 %B.gep.14 = getelementptr i8, i8* %B, i64 14 1104 %B.14 = load i8, i8* %B.gep.14 1105 %xor.14 = xor i8 %A.14, %B.14 1106 %A.gep.15 = getelementptr i8, i8* %A, i64 15 1107 %A.15 = load i8, i8* %A.gep.15 1108 %B.gep.15 = getelementptr i8, i8* %B, i64 15 1109 %B.15 = load i8, i8* %B.gep.15 1110 %xor.15 = xor i8 %A.15, %B.15 1111 %R.gep.0 = getelementptr i8, i8* %arg1, i64 0 1112 store i8 %xor.0, i8* %R.gep.0 1113 %R.gep.1 = getelementptr i8, i8* %arg1, i64 1 1114 store i8 %xor.1, i8* %R.gep.1 1115 %R.gep.2 = getelementptr i8, i8* %arg1, i64 2 1116 store i8 %xor.2, i8* %R.gep.2 1117 %R.gep.3 = getelementptr i8, i8* %arg1, i64 3 1118 store i8 %xor.3, i8* %R.gep.3 1119 %R.gep.4 = getelementptr i8, i8* %arg1, i64 4 1120 store i8 %xor.4, i8* %R.gep.4 1121 %R.gep.5 = getelementptr i8, i8* %arg1, i64 5 1122 store i8 %xor.5, i8* %R.gep.5 1123 %R.gep.6 = getelementptr i8, i8* %arg1, i64 6 1124 store i8 %xor.6, i8* %R.gep.6 1125 %R.gep.7 = getelementptr i8, i8* %arg1, i64 7 1126 store i8 %xor.7, i8* %R.gep.7 1127 %R.gep.8 = getelementptr i8, i8* %arg1, i64 8 1128 store i8 %xor.8, i8* %R.gep.8 1129 %R.gep.9 = getelementptr i8, i8* %arg1, i64 9 1130 store i8 %xor.9, i8* %R.gep.9 1131 %R.gep.10 = getelementptr i8, i8* %arg1, i64 10 1132 store i8 %xor.10, i8* %R.gep.10 1133 %R.gep.11 = getelementptr i8, i8* %arg1, i64 11 1134 store i8 %xor.11, i8* %R.gep.11 1135 %R.gep.12 = getelementptr i8, i8* %arg1, i64 12 1136 store i8 %xor.12, i8* %R.gep.12 1137 %R.gep.13 = getelementptr i8, i8* %arg1, i64 13 1138 store i8 %xor.13, i8* %R.gep.13 1139 %R.gep.14 = getelementptr i8, i8* %arg1, i64 14 1140 store i8 %xor.14, i8* %R.gep.14 1141 %R.gep.15 = getelementptr i8, i8* %arg1, i64 15 1142 store i8 %xor.15, i8* %R.gep.15 1143 1144 1145 %t21 = getelementptr inbounds i8, i8* %arg3, i64 15 1146 %t22 = bitcast i8* %arg3 to <16 x i8>* 1147 1148 call void @foo(i8* nonnull %t4) 1149 %t26 = load i8, i8* %arg3, align 1 1150 %t27 = load i8, i8* %arg2, align 1 1151 %t28 = xor i8 %t27, %t26 1152 store i8 %t28, i8* %arg2, align 1 1153 %t29 = load i8, i8* %t5, align 1 1154 %t30 = getelementptr inbounds i8, i8* %arg2, i64 1 1155 %t31 = load i8, i8* %t30, align 1 1156 %t32 = xor i8 %t31, %t29 1157 store i8 %t32, i8* %t30, align 1 1158 %t33 = load i8, i8* %t6, align 1 1159 %t34 = getelementptr inbounds i8, i8* %arg2, i64 2 1160 %t35 = load i8, i8* %t34, align 1 1161 %t36 = xor i8 %t35, %t33 1162 store i8 %t36, i8* %t34, align 1 1163 %t37 = load i8, i8* %t7, align 1 1164 %t38 = getelementptr inbounds i8, i8* %arg2, i64 3 1165 %t39 = load i8, i8* %t38, align 1 1166 %t40 = xor i8 %t39, %t37 1167 store i8 %t40, i8* %t38, align 1 1168 %t41 = load i8, i8* %t8, align 1 1169 %t42 = getelementptr inbounds i8, i8* %arg2, i64 4 1170 %t43 = load i8, i8* %t42, align 1 1171 %t44 = xor i8 %t43, %t41 1172 store i8 %t44, i8* %t42, align 1 1173 %t45 = load i8, i8* %t9, align 1 1174 %t46 = getelementptr inbounds i8, i8* %arg2, i64 5 1175 %t47 = load i8, i8* %t46, align 1 1176 %t48 = xor i8 %t47, %t45 1177 store i8 %t48, i8* %t46, align 1 1178 %t49 = load i8, i8* %t10, align 1 1179 %t50 = getelementptr inbounds i8, i8* %arg2, i64 6 1180 %t51 = load i8, i8* %t50, align 1 1181 %t52 = xor i8 %t51, %t49 1182 store i8 %t52, i8* %t50, align 1 1183 %t53 = load i8, i8* %t11, align 1 1184 %t54 = getelementptr inbounds i8, i8* %arg2, i64 7 1185 %t55 = load i8, i8* %t54, align 1 1186 %t56 = xor i8 %t55, %t53 1187 store i8 %t56, i8* %t54, align 1 1188 %t57 = load i8, i8* %t12, align 1 1189 %t58 = getelementptr inbounds i8, i8* %arg2, i64 8 1190 %t59 = load i8, i8* %t58, align 1 1191 %t60 = xor i8 %t59, %t57 1192 store i8 %t60, i8* %t58, align 1 1193 %t61 = load i8, i8* %t13, align 1 1194 %t62 = getelementptr inbounds i8, i8* %arg2, i64 9 1195 %t63 = load i8, i8* %t62, align 1 1196 %t64 = xor i8 %t63, %t61 1197 store i8 %t64, i8* %t62, align 1 1198 %t65 = load i8, i8* %t14, align 1 1199 %t66 = getelementptr inbounds i8, i8* %arg2, i64 10 1200 %t67 = load i8, i8* %t66, align 1 1201 %t68 = xor i8 %t67, %t65 1202 store i8 %t68, i8* %t66, align 1 1203 %t69 = load i8, i8* %t15, align 1 1204 %t70 = getelementptr inbounds i8, i8* %arg2, i64 11 1205 %t71 = load i8, i8* %t70, align 1 1206 %t72 = xor i8 %t71, %t69 1207 store i8 %t72, i8* %t70, align 1 1208 %t73 = load i8, i8* %t16, align 1 1209 %t74 = getelementptr inbounds i8, i8* %arg2, i64 12 1210 %t75 = load i8, i8* %t74, align 1 1211 %t76 = xor i8 %t75, %t73 1212 store i8 %t76, i8* %t74, align 1 1213 %t77 = load i8, i8* %t17, align 1 1214 %t78 = getelementptr inbounds i8, i8* %arg2, i64 13 1215 %t79 = load i8, i8* %t78, align 1 1216 %t80 = xor i8 %t79, %t77 1217 store i8 %t80, i8* %t78, align 1 1218 %t81 = load i8, i8* %t18, align 1 1219 %t82 = getelementptr inbounds i8, i8* %arg2, i64 14 1220 %t83 = load i8, i8* %t82, align 1 1221 %t84 = xor i8 %t83, %t81 1222 store i8 %t84, i8* %t82, align 1 1223 %t85 = load i8, i8* %t21, align 1 1224 %t86 = getelementptr inbounds i8, i8* %arg2, i64 15 1225 %t87 = load i8, i8* %t86, align 1 1226 %t88 = xor i8 %t87, %t85 1227 store i8 %t88, i8* %t86, align 1 1228 ret i32 1 1229} 1230 1231; A test case where instructions required to compute the pointer bounds get 1232; vectorized before versioning. Make sure there is no crash. 1233define void @crash_instructions_deleted(float* %t, i32* %a, i32** noalias %ptr) { 1234; CHECK-LABEL: @crash_instructions_deleted( 1235; CHECK-NEXT: bb: 1236; CHECK-NEXT: [[T15:%.*]] = getelementptr inbounds i32, i32* [[A:%.*]], i32 2 1237; CHECK-NEXT: [[T16:%.*]] = getelementptr inbounds i32, i32* [[A]], i32 3 1238; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[T15]] to <2 x i32>* 1239; CHECK-NEXT: store <2 x i32> <i32 0, i32 10>, <2 x i32>* [[TMP0]], align 8 1240; CHECK-NEXT: [[T17:%.*]] = load i32*, i32** [[PTR:%.*]], align 8 1241; CHECK-NEXT: br label [[BB18:%.*]] 1242; CHECK: bb18: 1243; CHECK-NEXT: [[T19:%.*]] = sext i32 0 to i64 1244; CHECK-NEXT: [[T20:%.*]] = add nsw i64 1, [[T19]] 1245; CHECK-NEXT: [[T21:%.*]] = getelementptr inbounds i32, i32* [[T17]], i64 [[T20]] 1246; CHECK-NEXT: [[T22:%.*]] = bitcast i32* [[T21]] to i8* 1247; CHECK-NEXT: [[T23:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 1 1248; CHECK-NEXT: [[T24:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 2 1249; CHECK-NEXT: [[T25:%.*]] = getelementptr inbounds i8, i8* [[T22]], i64 3 1250; CHECK-NEXT: [[T26:%.*]] = load i8, i8* [[T22]], align 1 1251; CHECK-NEXT: [[T27:%.*]] = uitofp i8 [[T26]] to float 1252; CHECK-NEXT: [[T28:%.*]] = fdiv float [[T27]], 2.550000e+02 1253; CHECK-NEXT: [[T29:%.*]] = getelementptr inbounds float, float* [[T:%.*]], i64 0 1254; CHECK-NEXT: store float [[T28]], float* [[T29]], align 8 1255; CHECK-NEXT: [[T30:%.*]] = load i8, i8* [[T23]], align 1 1256; CHECK-NEXT: [[T31:%.*]] = uitofp i8 [[T30]] to float 1257; CHECK-NEXT: [[T32:%.*]] = fdiv float [[T31]], 2.550000e+02 1258; CHECK-NEXT: [[T33:%.*]] = getelementptr inbounds float, float* [[T]], i64 1 1259; CHECK-NEXT: store float [[T32]], float* [[T33]], align 4 1260; CHECK-NEXT: [[T34:%.*]] = load i8, i8* [[T24]], align 1 1261; CHECK-NEXT: [[T35:%.*]] = uitofp i8 [[T34]] to float 1262; CHECK-NEXT: [[T36:%.*]] = fdiv float [[T35]], 2.550000e+02 1263; CHECK-NEXT: [[T37:%.*]] = getelementptr inbounds float, float* [[T]], i64 2 1264; CHECK-NEXT: store float [[T36]], float* [[T37]], align 8 1265; CHECK-NEXT: [[T38:%.*]] = load i8, i8* [[T25]], align 1 1266; CHECK-NEXT: [[T39:%.*]] = uitofp i8 [[T38]] to float 1267; CHECK-NEXT: [[T40:%.*]] = fdiv float [[T39]], 2.550000e+02 1268; CHECK-NEXT: [[T41:%.*]] = getelementptr inbounds float, float* [[T]], i64 3 1269; CHECK-NEXT: store float [[T40]], float* [[T41]], align 4 1270; CHECK-NEXT: ret void 1271; 1272bb: 1273 %t6 = icmp slt i32 10, 0 1274 %t7 = icmp sgt i32 20, 20 1275 %t9 = select i1 %t7, i32 5, i32 0 1276 %t10 = select i1 %t6, i32 0, i32 %t9 1277 %t11 = icmp slt i32 10, 0 1278 %t12 = icmp sgt i32 20, 20 1279 %t13 = select i1 %t12, i32 5, i32 10 1280 %t14 = select i1 %t11, i32 0, i32 %t13 1281 %t15 = getelementptr inbounds i32, i32* %a, i32 2 1282 store i32 %t10, i32* %t15, align 8 1283 %t16 = getelementptr inbounds i32, i32* %a, i32 3 1284 store i32 %t14, i32* %t16, align 4 1285 %t17 = load i32*, i32** %ptr, align 8 1286 br label %bb18 1287 1288bb18: ; preds = %bb5 1289 %t19 = sext i32 %t10 to i64 1290 %t20 = add nsw i64 1, %t19 1291 %t21 = getelementptr inbounds i32, i32* %t17, i64 %t20 1292 %t22 = bitcast i32* %t21 to i8* 1293 %t23 = getelementptr inbounds i8, i8* %t22, i64 1 1294 %t24 = getelementptr inbounds i8, i8* %t22, i64 2 1295 %t25 = getelementptr inbounds i8, i8* %t22, i64 3 1296 %t26 = load i8, i8* %t22, align 1 1297 %t27 = uitofp i8 %t26 to float 1298 %t28 = fdiv float %t27, 2.550000e+02 1299 %t29 = getelementptr inbounds float, float* %t, i64 0 1300 store float %t28, float* %t29, align 8 1301 %t30 = load i8, i8* %t23, align 1 1302 %t31 = uitofp i8 %t30 to float 1303 %t32 = fdiv float %t31, 2.550000e+02 1304 %t33 = getelementptr inbounds float, float* %t, i64 1 1305 store float %t32, float* %t33, align 4 1306 %t34 = load i8, i8* %t24, align 1 1307 %t35 = uitofp i8 %t34 to float 1308 %t36 = fdiv float %t35, 2.550000e+02 1309 %t37 = getelementptr inbounds float, float* %t, i64 2 1310 store float %t36, float* %t37, align 8 1311 %t38 = load i8, i8* %t25, align 1 1312 %t39 = uitofp i8 %t38 to float 1313 %t40 = fdiv float %t39, 2.550000e+02 1314 %t41 = getelementptr inbounds float, float* %t, i64 3 1315 store float %t40, float* %t41, align 4 1316 ret void 1317} 1318 1319; A test case where there are no instructions accessing a tracked object in a 1320; block for which versioning was requested. 1321define void @crash_no_tracked_instructions(float** %arg, float* %arg.2, float* %arg.3, i1 %c) { 1322; CHECK-LABEL: @crash_no_tracked_instructions( 1323; CHECK-NEXT: entry: 1324; CHECK-NEXT: [[T19:%.*]] = load float*, float** [[ARG:%.*]], align 8 1325; CHECK-NEXT: [[T20:%.*]] = load float, float* [[ARG_3:%.*]], align 4 1326; CHECK-NEXT: [[T21:%.*]] = getelementptr inbounds float, float* [[ARG_2:%.*]], i64 0 1327; CHECK-NEXT: br i1 [[C:%.*]], label [[BB22:%.*]], label [[BB30:%.*]] 1328; CHECK: bb22: 1329; CHECK-NEXT: [[T23:%.*]] = fmul float [[T20]], 9.900000e+01 1330; CHECK-NEXT: [[T24:%.*]] = fmul float [[T23]], 9.900000e+01 1331; CHECK-NEXT: [[T25:%.*]] = getelementptr inbounds float, float* [[T19]], i64 2 1332; CHECK-NEXT: [[T26:%.*]] = fmul float [[T23]], 1.000000e+01 1333; CHECK-NEXT: store float [[T26]], float* [[T25]], align 4 1334; CHECK-NEXT: [[T27:%.*]] = load float, float* [[T21]], align 8 1335; CHECK-NEXT: [[T28:%.*]] = fadd float [[T24]], 2.000000e+01 1336; CHECK-NEXT: [[T29:%.*]] = fadd float [[T26]], 2.000000e+01 1337; CHECK-NEXT: br label [[BB30]] 1338; CHECK: bb30: 1339; CHECK-NEXT: [[T31:%.*]] = phi float [ [[T28]], [[BB22]] ], [ 0.000000e+00, [[ENTRY:%.*]] ] 1340; CHECK-NEXT: [[T32:%.*]] = phi float [ [[T29]], [[BB22]] ], [ [[T20]], [[ENTRY]] ] 1341; CHECK-NEXT: br label [[BB36:%.*]] 1342; CHECK: bb36: 1343; CHECK-NEXT: [[T37:%.*]] = fmul float [[T31]], 3.000000e+00 1344; CHECK-NEXT: [[T38:%.*]] = getelementptr inbounds float, float* [[ARG_3]], i64 0 1345; CHECK-NEXT: store float [[T37]], float* [[T38]], align 4 1346; CHECK-NEXT: [[T39:%.*]] = fmul float [[T32]], 3.000000e+00 1347; CHECK-NEXT: [[T40:%.*]] = getelementptr inbounds float, float* [[ARG_3]], i64 1 1348; CHECK-NEXT: store float [[T39]], float* [[T40]], align 4 1349; CHECK-NEXT: br label [[BB41:%.*]] 1350; CHECK: bb41: 1351; CHECK-NEXT: ret void 1352; 1353entry: 1354 %t19 = load float*, float** %arg 1355 %t20 = load float, float* %arg.3, align 4 1356 %t21 = getelementptr inbounds float, float* %arg.2, i64 0 1357 br i1 %c, label %bb22, label %bb30 1358 1359bb22: 1360 %t23 = fmul float %t20, 99.0 1361 %t24 = fmul float %t23, 99.0 1362 %t25 = getelementptr inbounds float, float* %t19, i64 2 1363 %t26 = fmul float %t23, 10.0 1364 store float %t26, float* %t25, align 4 1365 %t27 = load float, float* %t21, align 8 1366 %t28 = fadd float %t24, 20.0 1367 %t29 = fadd float %t26, 20.0 1368 br label %bb30 1369 1370bb30: 1371 %t31 = phi float [ %t28, %bb22 ], [ 0.0, %entry ] 1372 %t32 = phi float [ %t29, %bb22 ], [ %t20, %entry ] 1373 br label %bb36 1374 1375bb36: 1376 %t37 = fmul float %t31, 3.0 1377 %t38 = getelementptr inbounds float, float* %arg.3, i64 0 1378 store float %t37, float* %t38, align 4 1379 %t39 = fmul float %t32, 3.0 1380 %t40 = getelementptr inbounds float, float* %arg.3, i64 1 1381 store float %t39, float* %t40, align 4 1382 br label %bb41 1383 1384bb41: 1385 ret void 1386} 1387