1; RUN: opt -mtriple=arm-arm-eabi -mcpu=cortex-m33 < %s -arm-parallel-dsp -verify -S | FileCheck %s 2; 3; Alias check: check that the rewrite isn't triggered when there's a store 4; instruction possibly aliasing any mul load operands; arguments are passed 5; without 'restrict' enabled. 6; 7; CHECK-NOT: call i32 @llvm.arm.smlad 8; 9define dso_local i32 @no_restrict(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 10entry: 11 %cmp24 = icmp sgt i32 %arg, 0 12 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 13 14for.body.preheader: 15 %.pre = load i16, i16* %arg3, align 2 16 %.pre27 = load i16, i16* %arg2, align 2 17 br label %for.body 18 19for.cond.cleanup: 20 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 21 ret i32 %mac1.0.lcssa 22 23for.body: 24 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 25 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 26 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 27 %0 = load i16, i16* %arrayidx, align 2 28 29; Store inserted here, aliasing with arrayidx, arrayidx1, arrayidx3 30 store i16 42, i16* %arrayidx, align 2 31 32 %add = add nuw nsw i32 %i.025, 1 33 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 34 %1 = load i16, i16* %arrayidx1, align 2 35 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 36 %2 = load i16, i16* %arrayidx3, align 2 37 %conv = sext i16 %2 to i32 38 %conv4 = sext i16 %0 to i32 39 %mul = mul nsw i32 %conv, %conv4 40 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 41 %3 = load i16, i16* %arrayidx6, align 2 42 %conv7 = sext i16 %3 to i32 43 %conv8 = sext i16 %1 to i32 44 %mul9 = mul nsw i32 %conv7, %conv8 45 %add10 = add i32 %mul, %mac1.026 46 %add11 = add i32 %mul9, %add10 47 %exitcond = icmp ne i32 %add, %arg 48 br i1 %exitcond, label %for.body, label %for.cond.cleanup 49} 50 51; Alias check: check that the rewrite isn't triggered when there's a store 52; aliasing one of the mul load operands. Arguments are now annotated with 53; 'noalias'. 54; 55; CHECK-NOT: call i32 @llvm.arm.smlad 56; 57define dso_local i32 @restrict(i32 %arg, i32* noalias %arg1, i16* noalias readonly %arg2, i16* noalias readonly %arg3) { 58entry: 59 %cmp24 = icmp sgt i32 %arg, 0 60 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 61 62for.body.preheader: 63 %.pre = load i16, i16* %arg3, align 2 64 %.pre27 = load i16, i16* %arg2, align 2 65 br label %for.body 66 67for.cond.cleanup: 68 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 69 ret i32 %mac1.0.lcssa 70 71for.body: 72 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 73 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 74 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 75 %0 = load i16, i16* %arrayidx, align 2 76 77; Store inserted here, aliasing only with loads from 'arrayidx'. 78 store i16 42, i16* %arrayidx, align 2 79 80 %add = add nuw nsw i32 %i.025, 1 81 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 82 %1 = load i16, i16* %arrayidx1, align 2 83 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 84 %2 = load i16, i16* %arrayidx3, align 2 85 %conv = sext i16 %2 to i32 86 %conv4 = sext i16 %0 to i32 87 %mul = mul nsw i32 %conv, %conv4 88 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 89 %3 = load i16, i16* %arrayidx6, align 2 90 %conv7 = sext i16 %3 to i32 91 %conv8 = sext i16 %1 to i32 92 %mul9 = mul nsw i32 %conv7, %conv8 93 %add10 = add i32 %mul, %mac1.026 94 95; Here the Mul is the LHS, and the Add the RHS. 96 %add11 = add i32 %mul9, %add10 97 98 %exitcond = icmp ne i32 %add, %arg 99 br i1 %exitcond, label %for.body, label %for.cond.cleanup 100} 101 102; CHECK-LABEL: store_dominates_all 103; CHECK: store 104; CHECK: load 105; CHECK: load 106; CHECK: load 107; CHECK: load 108; CHECK: smlad 109define dso_local i32 @store_dominates_all(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 110entry: 111 %cmp24 = icmp sgt i32 %arg, 0 112 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 113 114for.body.preheader: 115 %.pre = load i16, i16* %arg3, align 2 116 %.pre27 = load i16, i16* %arg2, align 2 117 br label %for.body 118 119for.cond.cleanup: 120 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 121 ret i32 %mac1.0.lcssa 122 123for.body: 124 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 125 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 126 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 127 store i16 42, i16* %arrayidx, align 2 128 %0 = load i16, i16* %arrayidx, align 2 129 %add = add nuw nsw i32 %i.025, 1 130 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 131 %1 = load i16, i16* %arrayidx1, align 2 132 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 133 %2 = load i16, i16* %arrayidx3, align 2 134 %conv = sext i16 %2 to i32 135 %conv4 = sext i16 %0 to i32 136 %mul = mul nsw i32 %conv, %conv4 137 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 138 %3 = load i16, i16* %arrayidx6, align 2 139 %conv7 = sext i16 %3 to i32 140 %conv8 = sext i16 %1 to i32 141 %mul9 = mul nsw i32 %conv7, %conv8 142 %add10 = add i32 %mul, %mac1.026 143 %add11 = add i32 %mul9, %add10 144 %exitcond = icmp ne i32 %add, %arg 145 br i1 %exitcond, label %for.body, label %for.cond.cleanup 146} 147 148; CHECK-LABEL: loads_dominate 149; CHECK-NOT: store 150; CHECK: load i32 151; CHECK-NOT: store 152; CHECK: load i32 153; CHECK: store 154define dso_local i32 @loads_dominate(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 155entry: 156 %cmp24 = icmp sgt i32 %arg, 0 157 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 158 159for.body.preheader: 160 %.pre = load i16, i16* %arg3, align 2 161 %.pre27 = load i16, i16* %arg2, align 2 162 br label %for.body 163 164for.cond.cleanup: 165 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 166 ret i32 %mac1.0.lcssa 167 168for.body: 169 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 170 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 171 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 172 %0 = load i16, i16* %arrayidx, align 2 173 %add = add nuw nsw i32 %i.025, 1 174 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 175 %1 = load i16, i16* %arrayidx1, align 2 176 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 177 %2 = load i16, i16* %arrayidx3, align 2 178 %conv = sext i16 %2 to i32 179 %conv4 = sext i16 %0 to i32 180 %mul = mul nsw i32 %conv, %conv4 181 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 182 %3 = load i16, i16* %arrayidx6, align 2 183 %conv7 = sext i16 %3 to i32 184 %conv8 = sext i16 %1 to i32 185 %mul9 = mul nsw i32 %conv7, %conv8 186 %add10 = add i32 %mul, %mac1.026 187 %add11 = add i32 %mul9, %add10 188 store i16 42, i16* %arrayidx, align 2 189 %exitcond = icmp ne i32 %add, %arg 190 br i1 %exitcond, label %for.body, label %for.cond.cleanup 191} 192 193; CHECK-LABEL: store_alias_arg3_legal_1 194; CHECK-NOT: store 195; CHECK: phi i32 196; CHECK: [[IV:%[^ ]+]] = phi i32 [ %add 197; CHECK: [[ARG3_GEP:%[^ ]+]] = getelementptr inbounds i16, i16* %arg3, i32 [[IV]] 198; CHECK: [[ARG3:%[^ ]+]] = bitcast i16* [[ARG3_GEP]] to i32* 199; CHECK: load i32, i32* [[ARG3]] 200; CHECK: [[ARG2_GEP:%[^ ]+]] = getelementptr inbounds i16, i16* %arg2, i32 [[IV]] 201; CHECK: [[ARG2:%[^ ]+]] = bitcast i16* [[ARG2_GEP]] to i32* 202; CHECK: load i32, i32* [[ARG2]] 203; CHECK: store 204define dso_local i32 @store_alias_arg3_legal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) { 205entry: 206 %cmp24 = icmp sgt i32 %arg, 0 207 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 208 209for.body.preheader: 210 %.pre = load i16, i16* %arg3, align 2 211 %.pre27 = load i16, i16* %arg2, align 2 212 br label %for.body 213 214for.cond.cleanup: 215 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 216 ret i32 %mac1.0.lcssa 217 218for.body: 219 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 220 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 221 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 222 %0 = load i16, i16* %arrayidx, align 2 223 %add = add nuw nsw i32 %i.025, 1 224 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 225 %1 = load i16, i16* %arrayidx1, align 2 226 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 227 %2 = load i16, i16* %arrayidx3, align 2 228 %conv = sext i16 %2 to i32 229 %conv4 = sext i16 %0 to i32 230 %mul = mul nsw i32 %conv, %conv4 231 store i16 42, i16* %arrayidx, align 2 232 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 233 %3 = load i16, i16* %arrayidx6, align 2 234 %conv7 = sext i16 %3 to i32 235 %conv8 = sext i16 %1 to i32 236 %mul9 = mul nsw i32 %conv7, %conv8 237 %add10 = add i32 %mul, %mac1.026 238 %add11 = add i32 %mul9, %add10 239 %exitcond = icmp ne i32 %add, %arg 240 br i1 %exitcond, label %for.body, label %for.cond.cleanup 241} 242 243; CHECK-LABEL: store_alias_arg3_legal_2 244; CHECK-NOT: store 245; CHECK: [[BITCAST:[^ ]+]] = bitcast i16* %arrayidx to i32* 246; CHECK: load i32, i32* [[BITCAST]] 247; CHECK: store i16 42, i16* %arrayidx 248; CHECK: [[BITCAST3:[^ ]+]] = bitcast i16* %arrayidx3 to i32* 249; CHECK: load i32, i32* [[BITCAST3]] 250; CHECK: smlad 251define dso_local i32 @store_alias_arg3_legal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* nocapture readonly %arg3) { 252entry: 253 %cmp24 = icmp sgt i32 %arg, 0 254 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 255 256for.body.preheader: 257 %.pre = load i16, i16* %arg3, align 2 258 %.pre27 = load i16, i16* %arg2, align 2 259 br label %for.body 260 261for.cond.cleanup: 262 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 263 ret i32 %mac1.0.lcssa 264 265for.body: 266 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 267 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 268 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 269 %0 = load i16, i16* %arrayidx, align 2 270 %add = add nuw nsw i32 %i.025, 1 271 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 272 %1 = load i16, i16* %arrayidx1, align 2 273 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 274 store i16 42, i16* %arrayidx, align 2 275 %2 = load i16, i16* %arrayidx3, align 2 276 %conv = sext i16 %2 to i32 277 %conv4 = sext i16 %0 to i32 278 %mul = mul nsw i32 %conv, %conv4 279 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 280 %3 = load i16, i16* %arrayidx6, align 2 281 %conv7 = sext i16 %3 to i32 282 %conv8 = sext i16 %1 to i32 283 %mul9 = mul nsw i32 %conv7, %conv8 284 %add10 = add i32 %mul, %mac1.026 285 %add11 = add i32 %mul9, %add10 286 %exitcond = icmp ne i32 %add, %arg 287 br i1 %exitcond, label %for.body, label %for.cond.cleanup 288} 289 290; CHECK-LABEL: store_alias_arg3_illegal_1 291; CHECK-NOT: load i32 292define dso_local i32 @store_alias_arg3_illegal_1(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) { 293entry: 294 %cmp24 = icmp sgt i32 %arg, 0 295 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 296 297for.body.preheader: 298 %.pre = load i16, i16* %arg3, align 2 299 %.pre27 = load i16, i16* %arg2, align 2 300 br label %for.body 301 302for.cond.cleanup: 303 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 304 ret i32 %mac1.0.lcssa 305 306for.body: 307 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 308 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 309 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 310 %0 = load i16, i16* %arrayidx, align 2 311 %add = add nuw nsw i32 %i.025, 1 312 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 313 store i16 42, i16* %arrayidx1, align 2 314 %1 = load i16, i16* %arrayidx1, align 2 315 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 316 %2 = load i16, i16* %arrayidx3, align 2 317 %conv = sext i16 %2 to i32 318 %conv4 = sext i16 %0 to i32 319 %mul = mul nsw i32 %conv, %conv4 320 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 321 %3 = load i16, i16* %arrayidx6, align 2 322 %conv7 = sext i16 %3 to i32 323 %conv8 = sext i16 %1 to i32 324 %mul9 = mul nsw i32 %conv7, %conv8 325 %add10 = add i32 %mul, %mac1.026 326 %add11 = add i32 %mul9, %add10 327 %exitcond = icmp ne i32 %add, %arg 328 br i1 %exitcond, label %for.body, label %for.cond.cleanup 329} 330 331; CHECK-LABEL: store_alias_arg3_illegal_2 332; CHECK-NOT: load i32 333define dso_local i32 @store_alias_arg3_illegal_2(i32 %arg, i32* nocapture %arg1, i16* noalias nocapture readonly %arg2, i16* noalias nocapture readonly %arg3) { 334entry: 335 %cmp24 = icmp sgt i32 %arg, 0 336 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 337 338for.body.preheader: 339 %.pre = load i16, i16* %arg3, align 2 340 %.pre27 = load i16, i16* %arg2, align 2 341 br label %for.body 342 343for.cond.cleanup: 344 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 345 ret i32 %mac1.0.lcssa 346 347for.body: 348 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 349 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 350 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 351 %0 = load i16, i16* %arrayidx, align 2 352 %add = add nuw nsw i32 %i.025, 1 353 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 354 store i16 42, i16* %arrayidx, align 2 355 %1 = load i16, i16* %arrayidx1, align 2 356 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 357 %2 = load i16, i16* %arrayidx3, align 2 358 %conv = sext i16 %2 to i32 359 %conv4 = sext i16 %0 to i32 360 %mul = mul nsw i32 %conv, %conv4 361 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 362 %3 = load i16, i16* %arrayidx6, align 2 363 %conv7 = sext i16 %3 to i32 364 %conv8 = sext i16 %1 to i32 365 %mul9 = mul nsw i32 %conv7, %conv8 366 %add10 = add i32 %mul, %mac1.026 367 %add11 = add i32 %mul9, %add10 368 %exitcond = icmp ne i32 %add, %arg 369 br i1 %exitcond, label %for.body, label %for.cond.cleanup 370} 371 372; CHECK-LABEL: store_alias_arg2_illegal_1 373; CHECK-NOT: load i32 374define dso_local i32 @store_alias_arg2_illegal_1(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 375entry: 376 %cmp24 = icmp sgt i32 %arg, 0 377 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 378 379for.body.preheader: 380 %.pre = load i16, i16* %arg3, align 2 381 %.pre27 = load i16, i16* %arg2, align 2 382 br label %for.body 383 384for.cond.cleanup: 385 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 386 ret i32 %mac1.0.lcssa 387 388for.body: 389 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 390 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 391 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 392 %0 = load i16, i16* %arrayidx, align 2 393 %add = add nuw nsw i32 %i.025, 1 394 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 395 %1 = load i16, i16* %arrayidx1, align 2 396 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 397 %2 = load i16, i16* %arrayidx3, align 2 398 %conv = sext i16 %2 to i32 399 %conv4 = sext i16 %0 to i32 400 %mul = mul nsw i32 %conv, %conv4 401 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 402 store i16 42, i16* %arrayidx6, align 2 403 %3 = load i16, i16* %arrayidx6, align 2 404 %conv7 = sext i16 %3 to i32 405 %conv8 = sext i16 %1 to i32 406 %mul9 = mul nsw i32 %conv7, %conv8 407 %add10 = add i32 %mul, %mac1.026 408 %add11 = add i32 %mul9, %add10 409 %exitcond = icmp ne i32 %add, %arg 410 br i1 %exitcond, label %for.body, label %for.cond.cleanup 411} 412 413; CHECK-LABEL: store_alias_arg2_illegal_2 414; CHECK-NOT: load i32 415define dso_local i32 @store_alias_arg2_illegal_2(i32 %arg, i32* nocapture %arg1, i16* nocapture readonly %arg2, i16* nocapture readonly %arg3) { 416entry: 417 %cmp24 = icmp sgt i32 %arg, 0 418 br i1 %cmp24, label %for.body.preheader, label %for.cond.cleanup 419 420for.body.preheader: 421 %.pre = load i16, i16* %arg3, align 2 422 %.pre27 = load i16, i16* %arg2, align 2 423 br label %for.body 424 425for.cond.cleanup: 426 %mac1.0.lcssa = phi i32 [ 0, %entry ], [ %add11, %for.body ] 427 ret i32 %mac1.0.lcssa 428 429for.body: 430 %mac1.026 = phi i32 [ %add11, %for.body ], [ 0, %for.body.preheader ] 431 %i.025 = phi i32 [ %add, %for.body ], [ 0, %for.body.preheader ] 432 %arrayidx = getelementptr inbounds i16, i16* %arg3, i32 %i.025 433 %0 = load i16, i16* %arrayidx, align 2 434 %add = add nuw nsw i32 %i.025, 1 435 %arrayidx1 = getelementptr inbounds i16, i16* %arg3, i32 %add 436 %1 = load i16, i16* %arrayidx1, align 2 437 %arrayidx3 = getelementptr inbounds i16, i16* %arg2, i32 %i.025 438 %2 = load i16, i16* %arrayidx3, align 2 439 %conv = sext i16 %2 to i32 440 %conv4 = sext i16 %0 to i32 441 %mul = mul nsw i32 %conv, %conv4 442 %arrayidx6 = getelementptr inbounds i16, i16* %arg2, i32 %add 443 store i16 42, i16* %arrayidx3, align 2 444 %3 = load i16, i16* %arrayidx6, align 2 445 %conv7 = sext i16 %3 to i32 446 %conv8 = sext i16 %1 to i32 447 %mul9 = mul nsw i32 %conv7, %conv8 448 %add10 = add i32 %mul, %mac1.026 449 %add11 = add i32 %mul9, %add10 450 %exitcond = icmp ne i32 %add, %arg 451 br i1 %exitcond, label %for.body, label %for.cond.cleanup 452} 453 454; TODO: I think we should be able to generate one smlad here. The search fails 455; when it finds the alias. 456; CHECK-LABEL: one_pair_alias 457; CHECK-NOT: call i32 @llvm.arm.smlad 458define i32 @one_pair_alias(i16* noalias nocapture readonly %b, i16* noalias nocapture readonly %c) { 459entry: 460 br label %for.body 461 462for.cond.cleanup: ; preds = %for.body 463 ret i32 %add26 464 465for.body: ; preds = %for.body, %entry 466 %i.050 = phi i32 [ 0, %entry ], [ %add27, %for.body ] 467 %a.049 = phi i32 [ 0, %entry ], [ %add26, %for.body ] 468 %add3 = or i32 %i.050, 1 469 %add11 = or i32 %i.050, 2 470 %add19 = or i32 %i.050, 3 471 %arrayidx = getelementptr inbounds i16, i16* %b, i32 %i.050 472 %arrayidx4 = getelementptr inbounds i16, i16* %b, i32 %add3 473 %arrayidx12 = getelementptr inbounds i16, i16* %b, i32 %add11 474 %arrayidx20 = getelementptr inbounds i16, i16* %b, i32 %add19 475 %arrayidx1 = getelementptr inbounds i16, i16* %c, i32 %i.050 476 %arrayidx7 = getelementptr inbounds i16, i16* %c, i32 %add3 477 %arrayidx15 = getelementptr inbounds i16, i16* %c, i32 %add11 478 %arrayidx23 = getelementptr inbounds i16, i16* %c, i32 %add19 479 %tmp = load i16, i16* %arrayidx, align 2 480 %tmp2 = load i16, i16* %arrayidx4, align 2 481 %tmp4 = load i16, i16* %arrayidx12, align 2 482 %tmp6 = load i16, i16* %arrayidx20, align 2 483 %tmp1 = load i16, i16* %arrayidx1, align 2 484 store i16 43, i16 *%arrayidx7 485 %tmp3 = load i16, i16* %arrayidx7, align 2 486 %tmp5 = load i16, i16* %arrayidx15, align 2 487 %tmp7 = load i16, i16* %arrayidx23, align 2 488 %conv = sext i16 %tmp to i32 489 %conv2 = sext i16 %tmp1 to i32 490 %mul = mul nsw i32 %conv2, %conv 491 %add = add nsw i32 %mul, %a.049 492 %conv5 = sext i16 %tmp2 to i32 493 %conv8 = sext i16 %tmp3 to i32 494 %mul9 = mul nsw i32 %conv8, %conv5 495 %add10 = add nsw i32 %add, %mul9 496 %conv13 = sext i16 %tmp4 to i32 497 %conv16 = sext i16 %tmp5 to i32 498 %mul17 = mul nsw i32 %conv16, %conv13 499 %add18 = add nsw i32 %add10, %mul17 500 %conv21 = sext i16 %tmp6 to i32 501 %conv24 = sext i16 %tmp7 to i32 502 %mul25 = mul nsw i32 %conv24, %conv21 503 %add26 = add nsw i32 %add18, %mul25 504 %add27 = add nuw nsw i32 %i.050, 4 505 %cmp = icmp ult i32 %add27, 100 506 br i1 %cmp, label %for.body, label %for.cond.cleanup 507} 508 509