479 lines · plain
1; RUN: opt -passes=loop-vectorize -debug-only=loop-vectorize -disable-output < %s 2>&1 | FileCheck %s2; REQUIRES: asserts3 4target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"5target triple = "thumbv8.1m.main-arm-none-eabi"6 7; Trip count of 5 - shouldn't be vectorized.8; CHECK-LABEL: tripcount59; CHECK: LV: Selecting VF: 110define void @tripcount5(ptr nocapture readonly %in, ptr nocapture %out, ptr nocapture readonly %consts, i32 %n) #0 {11entry:12 %arrayidx20 = getelementptr inbounds i32, ptr %out, i32 113 %arrayidx38 = getelementptr inbounds i32, ptr %out, i32 214 %arrayidx56 = getelementptr inbounds i32, ptr %out, i32 315 %arrayidx74 = getelementptr inbounds i32, ptr %out, i32 416 %arrayidx92 = getelementptr inbounds i32, ptr %out, i32 517 %arrayidx110 = getelementptr inbounds i32, ptr %out, i32 618 %arrayidx128 = getelementptr inbounds i32, ptr %out, i32 719 %out.promoted = load i32, ptr %out, align 420 %arrayidx20.promoted = load i32, ptr %arrayidx20, align 421 %arrayidx38.promoted = load i32, ptr %arrayidx38, align 422 %arrayidx56.promoted = load i32, ptr %arrayidx56, align 423 %arrayidx74.promoted = load i32, ptr %arrayidx74, align 424 %arrayidx92.promoted = load i32, ptr %arrayidx92, align 425 %arrayidx110.promoted = load i32, ptr %arrayidx110, align 426 %arrayidx128.promoted = load i32, ptr %arrayidx128, align 427 br label %for.body28 29for.cond.cleanup: ; preds = %for.body30 store i32 %add12, ptr %out, align 431 store i32 %add30, ptr %arrayidx20, align 432 store i32 %add48, ptr %arrayidx38, align 433 store i32 %add66, ptr %arrayidx56, align 434 store i32 %add84, ptr %arrayidx74, align 435 store i32 %add102, ptr %arrayidx92, align 436 store i32 %add120, ptr %arrayidx110, align 437 store i32 %add138, ptr %arrayidx128, align 438 ret void39 40for.body: ; preds = %entry, %for.body41 %hop.0236 = phi i32 [ 0, %entry ], [ %add139, %for.body ]42 %add12220235 = phi i32 [ %out.promoted, %entry ], [ %add12, %for.body ]43 %add30221234 = phi i32 [ %arrayidx20.promoted, %entry ], [ %add30, %for.body ]44 %add48222233 = phi i32 [ %arrayidx38.promoted, %entry ], [ %add48, %for.body ]45 %add66223232 = phi i32 [ %arrayidx56.promoted, %entry ], [ %add66, %for.body ]46 %add84224231 = phi i32 [ %arrayidx74.promoted, %entry ], [ %add84, %for.body ]47 %add102225230 = phi i32 [ %arrayidx92.promoted, %entry ], [ %add102, %for.body ]48 %add120226229 = phi i32 [ %arrayidx110.promoted, %entry ], [ %add120, %for.body ]49 %add138227228 = phi i32 [ %arrayidx128.promoted, %entry ], [ %add138, %for.body ]50 %arrayidx = getelementptr inbounds i16, ptr %in, i32 %hop.023651 %0 = load i16, ptr %arrayidx, align 252 %conv = sext i16 %0 to i3253 %arrayidx1 = getelementptr inbounds i16, ptr %consts, i32 %hop.023654 %1 = load i16, ptr %arrayidx1, align 255 %conv2 = sext i16 %1 to i3256 %mul = mul nsw i32 %conv2, %conv57 %add = add nsw i32 %mul, %add1222023558 %add4 = or i32 %hop.0236, 159 %arrayidx5 = getelementptr inbounds i16, ptr %in, i32 %add460 %2 = load i16, ptr %arrayidx5, align 261 %conv6 = sext i16 %2 to i3262 %arrayidx8 = getelementptr inbounds i16, ptr %consts, i32 %add463 %3 = load i16, ptr %arrayidx8, align 264 %conv9 = sext i16 %3 to i3265 %mul10 = mul nsw i32 %conv9, %conv666 %add12 = add nsw i32 %mul10, %add67 %add13 = or i32 %hop.0236, 268 %arrayidx14 = getelementptr inbounds i16, ptr %in, i32 %add1369 %4 = load i16, ptr %arrayidx14, align 270 %conv15 = sext i16 %4 to i3271 %arrayidx17 = getelementptr inbounds i16, ptr %consts, i32 %add1372 %5 = load i16, ptr %arrayidx17, align 273 %conv18 = sext i16 %5 to i3274 %mul19 = mul nsw i32 %conv18, %conv1575 %add21 = add nsw i32 %mul19, %add3022123476 %add22 = or i32 %hop.0236, 377 %arrayidx23 = getelementptr inbounds i16, ptr %in, i32 %add2278 %6 = load i16, ptr %arrayidx23, align 279 %conv24 = sext i16 %6 to i3280 %arrayidx26 = getelementptr inbounds i16, ptr %consts, i32 %add2281 %7 = load i16, ptr %arrayidx26, align 282 %conv27 = sext i16 %7 to i3283 %mul28 = mul nsw i32 %conv27, %conv2484 %add30 = add nsw i32 %mul28, %add2185 %add31 = or i32 %hop.0236, 486 %arrayidx32 = getelementptr inbounds i16, ptr %in, i32 %add3187 %8 = load i16, ptr %arrayidx32, align 288 %conv33 = sext i16 %8 to i3289 %arrayidx35 = getelementptr inbounds i16, ptr %consts, i32 %add3190 %9 = load i16, ptr %arrayidx35, align 291 %conv36 = sext i16 %9 to i3292 %mul37 = mul nsw i32 %conv36, %conv3393 %add39 = add nsw i32 %mul37, %add4822223394 %add40 = or i32 %hop.0236, 595 %arrayidx41 = getelementptr inbounds i16, ptr %in, i32 %add4096 %10 = load i16, ptr %arrayidx41, align 297 %conv42 = sext i16 %10 to i3298 %arrayidx44 = getelementptr inbounds i16, ptr %consts, i32 %add4099 %11 = load i16, ptr %arrayidx44, align 2100 %conv45 = sext i16 %11 to i32101 %mul46 = mul nsw i32 %conv45, %conv42102 %add48 = add nsw i32 %mul46, %add39103 %add49 = or i32 %hop.0236, 6104 %arrayidx50 = getelementptr inbounds i16, ptr %in, i32 %add49105 %12 = load i16, ptr %arrayidx50, align 2106 %conv51 = sext i16 %12 to i32107 %arrayidx53 = getelementptr inbounds i16, ptr %consts, i32 %add49108 %13 = load i16, ptr %arrayidx53, align 2109 %conv54 = sext i16 %13 to i32110 %mul55 = mul nsw i32 %conv54, %conv51111 %add57 = add nsw i32 %mul55, %add66223232112 %add58 = or i32 %hop.0236, 7113 %arrayidx59 = getelementptr inbounds i16, ptr %in, i32 %add58114 %14 = load i16, ptr %arrayidx59, align 2115 %conv60 = sext i16 %14 to i32116 %arrayidx62 = getelementptr inbounds i16, ptr %consts, i32 %add58117 %15 = load i16, ptr %arrayidx62, align 2118 %conv63 = sext i16 %15 to i32119 %mul64 = mul nsw i32 %conv63, %conv60120 %add66 = add nsw i32 %mul64, %add57121 %add67 = or i32 %hop.0236, 8122 %arrayidx68 = getelementptr inbounds i16, ptr %in, i32 %add67123 %16 = load i16, ptr %arrayidx68, align 2124 %conv69 = sext i16 %16 to i32125 %arrayidx71 = getelementptr inbounds i16, ptr %consts, i32 %add67126 %17 = load i16, ptr %arrayidx71, align 2127 %conv72 = sext i16 %17 to i32128 %mul73 = mul nsw i32 %conv72, %conv69129 %add75 = add nsw i32 %mul73, %add84224231130 %add76 = or i32 %hop.0236, 9131 %arrayidx77 = getelementptr inbounds i16, ptr %in, i32 %add76132 %18 = load i16, ptr %arrayidx77, align 2133 %conv78 = sext i16 %18 to i32134 %arrayidx80 = getelementptr inbounds i16, ptr %consts, i32 %add76135 %19 = load i16, ptr %arrayidx80, align 2136 %conv81 = sext i16 %19 to i32137 %mul82 = mul nsw i32 %conv81, %conv78138 %add84 = add nsw i32 %mul82, %add75139 %add85 = or i32 %hop.0236, 10140 %arrayidx86 = getelementptr inbounds i16, ptr %in, i32 %add85141 %20 = load i16, ptr %arrayidx86, align 2142 %conv87 = sext i16 %20 to i32143 %arrayidx89 = getelementptr inbounds i16, ptr %consts, i32 %add85144 %21 = load i16, ptr %arrayidx89, align 2145 %conv90 = sext i16 %21 to i32146 %mul91 = mul nsw i32 %conv90, %conv87147 %add93 = add nsw i32 %mul91, %add102225230148 %add94 = or i32 %hop.0236, 11149 %arrayidx95 = getelementptr inbounds i16, ptr %in, i32 %add94150 %22 = load i16, ptr %arrayidx95, align 2151 %conv96 = sext i16 %22 to i32152 %arrayidx98 = getelementptr inbounds i16, ptr %consts, i32 %add94153 %23 = load i16, ptr %arrayidx98, align 2154 %conv99 = sext i16 %23 to i32155 %mul100 = mul nsw i32 %conv99, %conv96156 %add102 = add nsw i32 %mul100, %add93157 %add103 = or i32 %hop.0236, 12158 %arrayidx104 = getelementptr inbounds i16, ptr %in, i32 %add103159 %24 = load i16, ptr %arrayidx104, align 2160 %conv105 = sext i16 %24 to i32161 %arrayidx107 = getelementptr inbounds i16, ptr %consts, i32 %add103162 %25 = load i16, ptr %arrayidx107, align 2163 %conv108 = sext i16 %25 to i32164 %mul109 = mul nsw i32 %conv108, %conv105165 %add111 = add nsw i32 %mul109, %add120226229166 %add112 = or i32 %hop.0236, 13167 %arrayidx113 = getelementptr inbounds i16, ptr %in, i32 %add112168 %26 = load i16, ptr %arrayidx113, align 2169 %conv114 = sext i16 %26 to i32170 %arrayidx116 = getelementptr inbounds i16, ptr %consts, i32 %add112171 %27 = load i16, ptr %arrayidx116, align 2172 %conv117 = sext i16 %27 to i32173 %mul118 = mul nsw i32 %conv117, %conv114174 %add120 = add nsw i32 %mul118, %add111175 %add121 = or i32 %hop.0236, 14176 %arrayidx122 = getelementptr inbounds i16, ptr %in, i32 %add121177 %28 = load i16, ptr %arrayidx122, align 2178 %conv123 = sext i16 %28 to i32179 %arrayidx125 = getelementptr inbounds i16, ptr %consts, i32 %add121180 %29 = load i16, ptr %arrayidx125, align 2181 %conv126 = sext i16 %29 to i32182 %mul127 = mul nsw i32 %conv126, %conv123183 %add129 = add nsw i32 %mul127, %add138227228184 %add130 = or i32 %hop.0236, 15185 %arrayidx131 = getelementptr inbounds i16, ptr %in, i32 %add130186 %30 = load i16, ptr %arrayidx131, align 2187 %conv132 = sext i16 %30 to i32188 %arrayidx134 = getelementptr inbounds i16, ptr %consts, i32 %add130189 %31 = load i16, ptr %arrayidx134, align 2190 %conv135 = sext i16 %31 to i32191 %mul136 = mul nsw i32 %conv135, %conv132192 %add138 = add nsw i32 %mul136, %add129193 %add139 = add nuw nsw i32 %hop.0236, 16194 %cmp = icmp ult i32 %hop.0236, 64195 br i1 %cmp, label %for.body, label %for.cond.cleanup196}197 198; Trip count of 8 - does get vectorized199; CHECK-LABEL: tripcount8200; CHECK: LV: Selecting VF: 4201define void @tripcount8(ptr nocapture readonly %in, ptr nocapture %out, ptr nocapture readonly %consts, i32 %n) #0 {202entry:203 %out.promoted = load i32, ptr %out, align 4204 br label %for.body205 206for.cond.cleanup: ; preds = %for.body207 store i32 %add12, ptr %out, align 4208 ret void209 210for.body: ; preds = %entry, %for.body211 %hop.0236 = phi i32 [ 0, %entry ], [ %add139, %for.body ]212 %add12220235 = phi i32 [ %out.promoted, %entry ], [ %add12, %for.body ]213 %arrayidx = getelementptr inbounds i16, ptr %in, i32 %hop.0236214 %0 = load i16, ptr %arrayidx, align 2215 %conv = sext i16 %0 to i32216 %arrayidx1 = getelementptr inbounds i16, ptr %consts, i32 %hop.0236217 %1 = load i16, ptr %arrayidx1, align 2218 %conv2 = sext i16 %1 to i32219 %mul = mul nsw i32 %conv2, %conv220 %add = add nsw i32 %mul, %add12220235221 %add4 = or i32 %hop.0236, 1222 %arrayidx5 = getelementptr inbounds i16, ptr %in, i32 %add4223 %2 = load i16, ptr %arrayidx5, align 2224 %conv6 = sext i16 %2 to i32225 %arrayidx8 = getelementptr inbounds i16, ptr %consts, i32 %add4226 %3 = load i16, ptr %arrayidx8, align 2227 %conv9 = sext i16 %3 to i32228 %mul10 = mul nsw i32 %conv9, %conv6229 %add12 = add nsw i32 %mul10, %add230 %add139 = add nuw nsw i32 %hop.0236, 16231 %cmp = icmp ult i32 %hop.0236, 112232 br i1 %cmp, label %for.body, label %for.cond.cleanup233}234 235; Larger example with predication that should also not be vectorized236; CHECK-LABEL: predicated_test237; CHECK: LV: Selecting VF: 1238; CHECK: LV: Selecting VF: 1239define dso_local i32 @predicated_test(i32 noundef %0, ptr %glob) #0 {240 %2 = alloca [101 x i32], align 4241 %3 = alloca [21 x i32], align 4242 call void @llvm.lifetime.start.p0(ptr nonnull %2)243 call void @llvm.lifetime.start.p0(ptr nonnull %3)244 %4 = icmp sgt i32 %0, 0245 br i1 %4, label %5, label %159246 2475: ; preds = %1248 %6 = getelementptr inbounds [21 x i32], ptr %3, i32 0, i32 5249 br label %7250 2517: ; preds = %5, %155252 %8 = phi i32 [ %10, %155 ], [ 0, %5 ]253 %9 = phi i32 [ %156, %155 ], [ 0, %5 ]254 %10 = shl i32 %8, 4255 store i32 %10, ptr %6, align 4256 br label %11257 25811: ; preds = %7, %152259 %12 = phi i32 [ 0, %7 ], [ %153, %152 ]260 %13 = lshr i32 %12, 3261 %14 = getelementptr inbounds [21 x i32], ptr %3, i32 0, i32 %13262 %15 = load i32, ptr %14, align 4263 %16 = shl nuw nsw i32 %12, 2264 %17 = and i32 %16, 28265 %18 = ashr i32 %15, %17266 %19 = and i32 %18, 15267 %20 = mul nuw nsw i32 %19, 5268 %21 = add nuw nsw i32 %20, 5269 %22 = getelementptr inbounds i32, ptr %glob, i32 %21270 %23 = mul nuw nsw i32 %12, 5271 br label %24272 27324: ; preds = %11, %78274 %25 = phi i32 [ 0, %11 ], [ %79, %78 ]275 %26 = add nuw nsw i32 %25, %23276 %27 = getelementptr inbounds [101 x i32], ptr %2, i32 0, i32 %26277 store i32 0, ptr %27, align 4278 %28 = getelementptr inbounds i32, ptr %22, i32 %25279 %29 = load i32, ptr %28, align 4280 %30 = and i32 %29, 1281 %31 = icmp eq i32 %30, 0282 %32 = and i32 %29, 2283 %33 = icmp eq i32 %32, 0284 %34 = and i32 %29, 4285 %35 = icmp eq i32 %34, 0286 %36 = and i32 %29, 8287 %37 = icmp eq i32 %36, 0288 %38 = and i32 %29, 16289 %39 = icmp eq i32 %38, 0290 %40 = and i32 %29, 32291 %41 = icmp eq i32 %40, 0292 %42 = and i32 %29, 64293 %43 = icmp eq i32 %42, 0294 %44 = and i32 %29, 128295 %45 = icmp eq i32 %44, 0296 %46 = and i32 %29, 254297 %47 = icmp eq i32 %46, 0298 br i1 %31, label %48, label %62299 30048: ; preds = %24301 %49 = select i1 %33, i32 0, i32 129302 %50 = or i32 %49, 258303 %51 = select i1 %35, i32 %49, i32 %50304 %52 = or i32 %51, 516305 %53 = select i1 %37, i32 %51, i32 %52306 %54 = or i32 %53, 1032307 %55 = select i1 %39, i32 %53, i32 %54308 %56 = or i32 %55, 2064309 %57 = select i1 %41, i32 %55, i32 %56310 %58 = or i32 %57, 4128311 %59 = select i1 %43, i32 %57, i32 %58312 %60 = or i32 %59, 8256313 %61 = select i1 %45, i32 %59, i32 %60314 br i1 %47, label %78, label %76315 31662: ; preds = %24317 %63 = select i1 %33, i32 0, i32 516318 %64 = or i32 %63, 1032319 %65 = select i1 %35, i32 %63, i32 %64320 %66 = or i32 %65, 2064321 %67 = select i1 %37, i32 %65, i32 %66322 %68 = or i32 %67, 4128323 %69 = select i1 %39, i32 %67, i32 %68324 %70 = or i32 %69, 8256325 %71 = select i1 %41, i32 %69, i32 %70326 %72 = or i32 %71, 16512327 %73 = select i1 %43, i32 %71, i32 %72328 %74 = or i32 %73, 33024329 %75 = select i1 %45, i32 %73, i32 %74330 br i1 %47, label %78, label %76331 33276: ; preds = %62, %48333 %77 = phi i32 [ %61, %48 ], [ %75, %62 ]334 store i32 %77, ptr %27, align 4335 br label %78336 33778: ; preds = %76, %62, %48338 %79 = add nuw nsw i32 %25, 1339 %80 = icmp eq i32 %79, 5340 br i1 %80, label %81, label %24341 34281: ; preds = %78343 br label %82344 34582: ; preds = %81, %149346 %83 = phi i32 [ %150, %149 ], [ 0, %81 ]347 %84 = add nuw nsw i32 %83, %23348 %85 = getelementptr inbounds [101 x i32], ptr %2, i32 0, i32 %84349 %86 = load i32, ptr %85, align 4350 %87 = shl i32 %86, 30351 %88 = and i32 %87, 1073741824352 %89 = and i32 %86, 2353 %90 = icmp eq i32 %89, 0354 %91 = select i1 %90, i32 %88, i32 1073741824355 %92 = shl i32 %86, 27356 %93 = and i32 %92, 536870912357 %94 = or i32 %91, %93358 %95 = shl i32 %86, 25359 %96 = and i32 %95, 268435456360 %97 = or i32 %94, %96361 %98 = shl i32 %86, 23362 %99 = and i32 %98, 134217728363 %100 = or i32 %97, %99364 %101 = or i32 %100, %86365 %102 = and i32 %86, 31366 %103 = and i32 %101, 32367 %104 = shl nuw nsw i32 %103, 21368 %105 = or i32 %102, %103369 %106 = and i32 %101, 64370 %107 = shl nuw nsw i32 %106, 19371 %108 = or i32 %104, %107372 %109 = or i32 %105, %106373 %110 = and i32 %101, 128374 %111 = shl nuw nsw i32 %110, 17375 %112 = or i32 %108, %111376 %113 = or i32 %109, %110377 %114 = and i32 %101, 256378 %115 = shl nuw nsw i32 %114, 15379 %116 = or i32 %112, %115380 %117 = or i32 %113, %114381 %118 = and i32 %101, 512382 %119 = shl nuw nsw i32 %118, 13383 %120 = or i32 %116, %119384 %121 = or i32 %120, %101385 %122 = or i32 %117, %118386 %123 = and i32 %121, 1024387 %124 = shl nuw nsw i32 %123, 11388 %125 = or i32 %122, %123389 %126 = and i32 %121, 2048390 %127 = shl nuw nsw i32 %126, 9391 %128 = or i32 %124, %127392 %129 = or i32 %125, %126393 %130 = and i32 %121, 4096394 %131 = shl nuw nsw i32 %130, 7395 %132 = or i32 %128, %131396 %133 = or i32 %129, %130397 %134 = and i32 %121, 8192398 %135 = shl nuw nsw i32 %134, 5399 %136 = or i32 %132, %135400 %137 = or i32 %136, %121401 %138 = or i32 %133, %134402 %139 = and i32 %137, 16384403 %140 = or i32 %138, %139404 %141 = and i32 %137, 32768405 %142 = or i32 %140, %141406 %143 = icmp eq i32 %142, 0407 br i1 %143, label %149, label %144408 409144: ; preds = %82410 %145 = shl nuw nsw i32 %139, 3411 %146 = shl nuw nsw i32 %141, 1412 %147 = or i32 %145, %146413 %148 = or i32 %147, %137414 store i32 %148, ptr %85, align 4415 br label %149416 417149: ; preds = %82, %144418 %150 = add nuw nsw i32 %83, 1419 %151 = icmp eq i32 %150, 5420 br i1 %151, label %152, label %82421 422152: ; preds = %149423 %153 = add nuw nsw i32 %12, 1424 %154 = icmp eq i32 %153, 20425 br i1 %154, label %155, label %11426 427155: ; preds = %152428 %156 = add nuw nsw i32 %9, 1429 %157 = icmp eq i32 %156, %0430 br i1 %157, label %158, label %7431 432158: ; preds = %155433 br label %159434 435159: ; preds = %158, %1436 call void @llvm.lifetime.end.p0(ptr nonnull %3)437 call void @llvm.lifetime.end.p0(ptr nonnull %2)438 ret i32 0439}440 441; This has a maximum trip count of 4. The codegen is currently much better with <8 x half> vectorization.442; CHECK-LABEL: arm_q15_to_f16_remainder443; CHECK: LV: Selecting VF: 8444define void @arm_q15_to_f16_remainder(ptr nocapture noundef readonly %pSrc, ptr nocapture noundef writeonly noalias %pDst, i32 noundef %blockSize) #0 {445entry:446 %rem = and i32 %blockSize, 3447 %cmp.not5 = icmp eq i32 %rem, 0448 br i1 %cmp.not5, label %while.end, label %while.body.preheader449 450while.body.preheader: ; preds = %entry451 br label %while.body452 453while.body: ; preds = %while.body.preheader, %while.body454 %blkCnt.08 = phi i32 [ %dec, %while.body ], [ %rem, %while.body.preheader ]455 %pIn.07 = phi ptr [ %incdec.ptr, %while.body ], [ %pSrc, %while.body.preheader ]456 %pDst.addr.06 = phi ptr [ %incdec.ptr2, %while.body ], [ %pDst, %while.body.preheader ]457 %incdec.ptr = getelementptr inbounds i8, ptr %pIn.07, i32 2458 %0 = load i16, ptr %pIn.07, align 2459 %conv1 = sitofp i16 %0 to half460 %1 = fmul fast half %conv1, 0xH0200461 %incdec.ptr2 = getelementptr inbounds i8, ptr %pDst.addr.06, i32 2462 store half %1, ptr %pDst.addr.06, align 2463 %dec = add nsw i32 %blkCnt.08, -1464 %cmp.not = icmp eq i32 %dec, 0465 br i1 %cmp.not, label %while.end.loopexit, label %while.body466 467while.end.loopexit: ; preds = %while.body468 br label %while.end469 470while.end: ; preds = %while.end.loopexit, %entry471 ret void472}473 474 475declare void @llvm.lifetime.start.p0(ptr)476declare void @llvm.lifetime.end.p0(ptr)477 478attributes #0 = { "target-features"="+mve.fp" }479