[llvm] [x86][CostModel] A runtime stride should cost one ADD on AVX2+ (PR #219903)

Le Gia Bao via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 00:39:03 PDT 2026


https://github.com/L3GiaBao created https://github.com/llvm/llvm-project/pull/219903

Runtime stride should cost one ADD per iteration. Only when the loop has no fixed step do we need the AVX2 cut-off.

Closes #217019.

>From 370a55765c6439b2f6da1a3c7c7a5fa89e70c48e Mon Sep 17 00:00:00 2001
From: Le Gia Bao <legiabao7300 at gmail.com>
Date: Mon, 31 Aug 2026 14:32:53 +0700
Subject: [PATCH] [x86][CostModel] A runtime stride should cost one ADD on
 AVX2+

---
 .../lib/Target/X86/X86TargetTransformInfo.cpp |  14 +-
 .../Transforms/LoopVectorize/X86/pr217019.ll  | 446 ++++++++++++++++++
 .../X86/replicating-load-store-costs.ll       |  66 +--
 3 files changed, 469 insertions(+), 57 deletions(-)
 create mode 100644 llvm/test/Transforms/LoopVectorize/X86/pr217019.ll

diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
index 8e0cf1fc5a153..4d8eede76a843 100644
--- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
+++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp
@@ -5723,13 +5723,15 @@ X86TTIImpl::getAddressComputationCost(Type *PtrTy, ScalarEvolution *SE,
   // Even in the case of (loop invariant) stride whose value is not known at
   // compile time, the address computation will not incur more than one extra
   // ADD instruction.
-  if (PtrTy->isVectorTy() && SE && !ST->hasAVX2()) {
-    // TODO: AVX2 is the current cut-off because we don't have correct
-    //       interleaving costs for prior ISA's.
-    if (!BaseT::isStridedAccess(Ptr))
-      return NumVectorInstToHideOverhead;
-    if (!BaseT::getConstantStrideStep(SE, Ptr))
+  if (PtrTy->isVectorTy() && SE) {
+    if (BaseT::isStridedAccess(Ptr) && !BaseT::getConstantStrideStep(SE, Ptr))
       return 1;
+    if (!ST->hasAVX2()) {
+      // TODO: AVX2 is the current cut-off because we don't have correct
+      //       interleaving costs for prior ISA's.
+      if (!BaseT::isStridedAccess(Ptr))
+        return NumVectorInstToHideOverhead;
+    }
   }
 
   return BaseT::getAddressComputationCost(PtrTy, SE, Ptr, CostKind);
diff --git a/llvm/test/Transforms/LoopVectorize/X86/pr217019.ll b/llvm/test/Transforms/LoopVectorize/X86/pr217019.ll
new file mode 100644
index 0000000000000..b9686db2ac824
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/X86/pr217019.ll
@@ -0,0 +1,446 @@
+; RUN: opt -passes=loop-vectorize -mtriple=x86_64-linux-gnu -mattr=+avx2 -S %s | FileCheck %s
+; RUN: opt -passes=loop-vectorize -mtriple=x86_64-linux-gnu -mattr=+avx512f,+avx512bw -S %s | FileCheck %s
+
+; Test case for https://github.com/llvm/llvm-project/issues/217019.
+
+define i32 @satd8_derived(ptr nofree noundef readonly captures(none) %src1, i64 noundef %stride1, ptr nofree noundef readonly captures(none) %src2, i64 noundef %stride2) local_unnamed_addr {
+; CHECK-LABEL: define i32 @satd8_derived(
+; CHECK-NOT: vector.body:
+;
+entry:
+  br label %.preheader
+
+.preheader:                                       ; preds = %entry, %.preheader
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %.preheader ]
+  %sum = phi i32 [ 0, %entry ], [ %427, %.preheader ]
+  %5 = mul nsw i64 %stride1, %indvars.iv
+  %6 = getelementptr inbounds [2 x i8], ptr %src1, i64 %5
+  %7 = mul nsw i64 %stride2, %indvars.iv
+  %8 = getelementptr inbounds [2 x i8], ptr %src2, i64 %7
+  %9 = load i16, ptr %6, align 2
+  %10 = zext i16 %9 to i64
+  %11 = load i16, ptr %8, align 2
+  %12 = zext i16 %11 to i64
+  %13 = sub nsw i64 %10, %12
+  %14 = getelementptr inbounds nuw i8, ptr %6, i64 8
+  %15 = load i16, ptr %14, align 2
+  %16 = zext i16 %15 to i64
+  %17 = getelementptr inbounds nuw i8, ptr %8, i64 8
+  %18 = load i16, ptr %17, align 2
+  %19 = zext i16 %18 to i64
+  %20 = sub nsw i64 %16, %19
+  %21 = shl nsw i64 %20, 32
+  %22 = add nsw i64 %21, %13
+  %23 = getelementptr inbounds nuw i8, ptr %6, i64 2
+  %24 = load i16, ptr %23, align 2
+  %25 = zext i16 %24 to i64
+  %26 = getelementptr inbounds nuw i8, ptr %8, i64 2
+  %27 = load i16, ptr %26, align 2
+  %28 = zext i16 %27 to i64
+  %29 = sub nsw i64 %25, %28
+  %30 = getelementptr inbounds nuw i8, ptr %6, i64 10
+  %31 = load i16, ptr %30, align 2
+  %32 = zext i16 %31 to i64
+  %33 = getelementptr inbounds nuw i8, ptr %8, i64 10
+  %34 = load i16, ptr %33, align 2
+  %35 = zext i16 %34 to i64
+  %36 = sub nsw i64 %32, %35
+  %37 = shl nsw i64 %36, 32
+  %38 = add nsw i64 %37, %29
+  %39 = getelementptr inbounds nuw i8, ptr %6, i64 4
+  %40 = load i16, ptr %39, align 2
+  %41 = zext i16 %40 to i64
+  %42 = getelementptr inbounds nuw i8, ptr %8, i64 4
+  %43 = load i16, ptr %42, align 2
+  %44 = zext i16 %43 to i64
+  %45 = sub nsw i64 %41, %44
+  %46 = getelementptr inbounds nuw i8, ptr %6, i64 12
+  %47 = load i16, ptr %46, align 2
+  %48 = zext i16 %47 to i64
+  %49 = getelementptr inbounds nuw i8, ptr %8, i64 12
+  %50 = load i16, ptr %49, align 2
+  %51 = zext i16 %50 to i64
+  %52 = sub nsw i64 %48, %51
+  %53 = shl nsw i64 %52, 32
+  %54 = add nsw i64 %53, %45
+  %55 = getelementptr inbounds nuw i8, ptr %6, i64 6
+  %56 = load i16, ptr %55, align 2
+  %57 = zext i16 %56 to i64
+  %58 = getelementptr inbounds nuw i8, ptr %8, i64 6
+  %59 = load i16, ptr %58, align 2
+  %60 = zext i16 %59 to i64
+  %61 = sub nsw i64 %57, %60
+  %62 = getelementptr inbounds nuw i8, ptr %6, i64 14
+  %63 = load i16, ptr %62, align 2
+  %64 = zext i16 %63 to i64
+  %65 = getelementptr inbounds nuw i8, ptr %8, i64 14
+  %66 = load i16, ptr %65, align 2
+  %67 = zext i16 %66 to i64
+  %68 = sub nsw i64 %64, %67
+  %69 = shl nsw i64 %68, 32
+  %70 = add nsw i64 %69, %61
+  %71 = add nsw i64 %38, %22
+  %72 = sub nsw i64 %22, %38
+  %73 = add nsw i64 %70, %54
+  %74 = sub nsw i64 %54, %70
+  %75 = add nsw i64 %73, %71
+  %76 = sub nsw i64 %71, %73
+  %77 = add nsw i64 %74, %72
+  %78 = sub nsw i64 %72, %74
+  %79 = getelementptr inbounds [2 x i8], ptr %6, i64 %stride1
+  %80 = getelementptr inbounds [2 x i8], ptr %8, i64 %stride2
+  %81 = load i16, ptr %79, align 2
+  %82 = zext i16 %81 to i64
+  %83 = load i16, ptr %80, align 2
+  %84 = zext i16 %83 to i64
+  %85 = sub nsw i64 %82, %84
+  %86 = getelementptr inbounds nuw i8, ptr %79, i64 8
+  %87 = load i16, ptr %86, align 2
+  %88 = zext i16 %87 to i64
+  %89 = getelementptr inbounds nuw i8, ptr %80, i64 8
+  %90 = load i16, ptr %89, align 2
+  %91 = zext i16 %90 to i64
+  %92 = sub nsw i64 %88, %91
+  %93 = shl nsw i64 %92, 32
+  %94 = add nsw i64 %93, %85
+  %95 = getelementptr inbounds nuw i8, ptr %79, i64 2
+  %96 = load i16, ptr %95, align 2
+  %97 = zext i16 %96 to i64
+  %98 = getelementptr inbounds nuw i8, ptr %80, i64 2
+  %99 = load i16, ptr %98, align 2
+  %100 = zext i16 %99 to i64
+  %101 = sub nsw i64 %97, %100
+  %102 = getelementptr inbounds nuw i8, ptr %79, i64 10
+  %103 = load i16, ptr %102, align 2
+  %104 = zext i16 %103 to i64
+  %105 = getelementptr inbounds nuw i8, ptr %80, i64 10
+  %106 = load i16, ptr %105, align 2
+  %107 = zext i16 %106 to i64
+  %108 = sub nsw i64 %104, %107
+  %109 = shl nsw i64 %108, 32
+  %110 = add nsw i64 %109, %101
+  %111 = getelementptr inbounds nuw i8, ptr %79, i64 4
+  %112 = load i16, ptr %111, align 2
+  %113 = zext i16 %112 to i64
+  %114 = getelementptr inbounds nuw i8, ptr %80, i64 4
+  %115 = load i16, ptr %114, align 2
+  %116 = zext i16 %115 to i64
+  %117 = sub nsw i64 %113, %116
+  %118 = getelementptr inbounds nuw i8, ptr %79, i64 12
+  %119 = load i16, ptr %118, align 2
+  %120 = zext i16 %119 to i64
+  %121 = getelementptr inbounds nuw i8, ptr %80, i64 12
+  %122 = load i16, ptr %121, align 2
+  %123 = zext i16 %122 to i64
+  %124 = sub nsw i64 %120, %123
+  %125 = shl nsw i64 %124, 32
+  %126 = add nsw i64 %125, %117
+  %127 = getelementptr inbounds nuw i8, ptr %79, i64 6
+  %128 = load i16, ptr %127, align 2
+  %129 = zext i16 %128 to i64
+  %130 = getelementptr inbounds nuw i8, ptr %80, i64 6
+  %131 = load i16, ptr %130, align 2
+  %132 = zext i16 %131 to i64
+  %133 = sub nsw i64 %129, %132
+  %134 = getelementptr inbounds nuw i8, ptr %79, i64 14
+  %135 = load i16, ptr %134, align 2
+  %136 = zext i16 %135 to i64
+  %137 = getelementptr inbounds nuw i8, ptr %80, i64 14
+  %138 = load i16, ptr %137, align 2
+  %139 = zext i16 %138 to i64
+  %140 = sub nsw i64 %136, %139
+  %141 = shl nsw i64 %140, 32
+  %142 = add nsw i64 %141, %133
+  %143 = add nsw i64 %110, %94
+  %144 = sub nsw i64 %94, %110
+  %145 = add nsw i64 %142, %126
+  %146 = sub nsw i64 %126, %142
+  %147 = add nsw i64 %145, %143
+  %148 = sub nsw i64 %143, %145
+  %149 = add nsw i64 %146, %144
+  %150 = sub nsw i64 %144, %146
+  %151 = getelementptr inbounds [2 x i8], ptr %79, i64 %stride1
+  %152 = getelementptr inbounds [2 x i8], ptr %80, i64 %stride2
+  %153 = load i16, ptr %151, align 2
+  %154 = zext i16 %153 to i64
+  %155 = load i16, ptr %152, align 2
+  %156 = zext i16 %155 to i64
+  %157 = sub nsw i64 %154, %156
+  %158 = getelementptr inbounds nuw i8, ptr %151, i64 8
+  %159 = load i16, ptr %158, align 2
+  %160 = zext i16 %159 to i64
+  %161 = getelementptr inbounds nuw i8, ptr %152, i64 8
+  %162 = load i16, ptr %161, align 2
+  %163 = zext i16 %162 to i64
+  %164 = sub nsw i64 %160, %163
+  %165 = shl nsw i64 %164, 32
+  %166 = add nsw i64 %165, %157
+  %167 = getelementptr inbounds nuw i8, ptr %151, i64 2
+  %168 = load i16, ptr %167, align 2
+  %169 = zext i16 %168 to i64
+  %170 = getelementptr inbounds nuw i8, ptr %152, i64 2
+  %171 = load i16, ptr %170, align 2
+  %172 = zext i16 %171 to i64
+  %173 = sub nsw i64 %169, %172
+  %174 = getelementptr inbounds nuw i8, ptr %151, i64 10
+  %175 = load i16, ptr %174, align 2
+  %176 = zext i16 %175 to i64
+  %177 = getelementptr inbounds nuw i8, ptr %152, i64 10
+  %178 = load i16, ptr %177, align 2
+  %179 = zext i16 %178 to i64
+  %180 = sub nsw i64 %176, %179
+  %181 = shl nsw i64 %180, 32
+  %182 = add nsw i64 %181, %173
+  %183 = getelementptr inbounds nuw i8, ptr %151, i64 4
+  %184 = load i16, ptr %183, align 2
+  %185 = zext i16 %184 to i64
+  %186 = getelementptr inbounds nuw i8, ptr %152, i64 4
+  %187 = load i16, ptr %186, align 2
+  %188 = zext i16 %187 to i64
+  %189 = sub nsw i64 %185, %188
+  %190 = getelementptr inbounds nuw i8, ptr %151, i64 12
+  %191 = load i16, ptr %190, align 2
+  %192 = zext i16 %191 to i64
+  %193 = getelementptr inbounds nuw i8, ptr %152, i64 12
+  %194 = load i16, ptr %193, align 2
+  %195 = zext i16 %194 to i64
+  %196 = sub nsw i64 %192, %195
+  %197 = shl nsw i64 %196, 32
+  %198 = add nsw i64 %197, %189
+  %199 = getelementptr inbounds nuw i8, ptr %151, i64 6
+  %200 = load i16, ptr %199, align 2
+  %201 = zext i16 %200 to i64
+  %202 = getelementptr inbounds nuw i8, ptr %152, i64 6
+  %203 = load i16, ptr %202, align 2
+  %204 = zext i16 %203 to i64
+  %205 = sub nsw i64 %201, %204
+  %206 = getelementptr inbounds nuw i8, ptr %151, i64 14
+  %207 = load i16, ptr %206, align 2
+  %208 = zext i16 %207 to i64
+  %209 = getelementptr inbounds nuw i8, ptr %152, i64 14
+  %210 = load i16, ptr %209, align 2
+  %211 = zext i16 %210 to i64
+  %212 = sub nsw i64 %208, %211
+  %213 = shl nsw i64 %212, 32
+  %214 = add nsw i64 %213, %205
+  %215 = add nsw i64 %182, %166
+  %216 = sub nsw i64 %166, %182
+  %217 = add nsw i64 %214, %198
+  %218 = sub nsw i64 %198, %214
+  %219 = add nsw i64 %217, %215
+  %220 = sub nsw i64 %215, %217
+  %221 = add nsw i64 %218, %216
+  %222 = sub nsw i64 %216, %218
+  %223 = getelementptr inbounds [2 x i8], ptr %151, i64 %stride1
+  %224 = getelementptr inbounds [2 x i8], ptr %152, i64 %stride2
+  %225 = load i16, ptr %223, align 2
+  %226 = zext i16 %225 to i64
+  %227 = load i16, ptr %224, align 2
+  %228 = zext i16 %227 to i64
+  %229 = sub nsw i64 %226, %228
+  %230 = getelementptr inbounds nuw i8, ptr %223, i64 8
+  %231 = load i16, ptr %230, align 2
+  %232 = zext i16 %231 to i64
+  %233 = getelementptr inbounds nuw i8, ptr %224, i64 8
+  %234 = load i16, ptr %233, align 2
+  %235 = zext i16 %234 to i64
+  %236 = sub nsw i64 %232, %235
+  %237 = shl nsw i64 %236, 32
+  %238 = add nsw i64 %237, %229
+  %239 = getelementptr inbounds nuw i8, ptr %223, i64 2
+  %240 = load i16, ptr %239, align 2
+  %241 = zext i16 %240 to i64
+  %242 = getelementptr inbounds nuw i8, ptr %224, i64 2
+  %243 = load i16, ptr %242, align 2
+  %244 = zext i16 %243 to i64
+  %245 = sub nsw i64 %241, %244
+  %246 = getelementptr inbounds nuw i8, ptr %223, i64 10
+  %247 = load i16, ptr %246, align 2
+  %248 = zext i16 %247 to i64
+  %249 = getelementptr inbounds nuw i8, ptr %224, i64 10
+  %250 = load i16, ptr %249, align 2
+  %251 = zext i16 %250 to i64
+  %252 = sub nsw i64 %248, %251
+  %253 = shl nsw i64 %252, 32
+  %254 = add nsw i64 %253, %245
+  %255 = getelementptr inbounds nuw i8, ptr %223, i64 4
+  %256 = load i16, ptr %255, align 2
+  %257 = zext i16 %256 to i64
+  %258 = getelementptr inbounds nuw i8, ptr %224, i64 4
+  %259 = load i16, ptr %258, align 2
+  %260 = zext i16 %259 to i64
+  %261 = sub nsw i64 %257, %260
+  %262 = getelementptr inbounds nuw i8, ptr %223, i64 12
+  %263 = load i16, ptr %262, align 2
+  %264 = zext i16 %263 to i64
+  %265 = getelementptr inbounds nuw i8, ptr %224, i64 12
+  %266 = load i16, ptr %265, align 2
+  %267 = zext i16 %266 to i64
+  %268 = sub nsw i64 %264, %267
+  %269 = shl nsw i64 %268, 32
+  %270 = add nsw i64 %269, %261
+  %271 = getelementptr inbounds nuw i8, ptr %223, i64 6
+  %272 = load i16, ptr %271, align 2
+  %273 = zext i16 %272 to i64
+  %274 = getelementptr inbounds nuw i8, ptr %224, i64 6
+  %275 = load i16, ptr %274, align 2
+  %276 = zext i16 %275 to i64
+  %277 = sub nsw i64 %273, %276
+  %278 = getelementptr inbounds nuw i8, ptr %223, i64 14
+  %279 = load i16, ptr %278, align 2
+  %280 = zext i16 %279 to i64
+  %281 = getelementptr inbounds nuw i8, ptr %224, i64 14
+  %282 = load i16, ptr %281, align 2
+  %283 = zext i16 %282 to i64
+  %284 = sub nsw i64 %280, %283
+  %285 = shl nsw i64 %284, 32
+  %286 = add nsw i64 %285, %277
+  %287 = add nsw i64 %254, %238
+  %288 = sub nsw i64 %238, %254
+  %289 = add nsw i64 %286, %270
+  %290 = sub nsw i64 %270, %286
+  %291 = add nsw i64 %289, %287
+  %292 = sub nsw i64 %287, %289
+  %293 = add nsw i64 %290, %288
+  %294 = sub nsw i64 %288, %290
+  %295 = add nsw i64 %147, %75
+  %296 = sub nsw i64 %75, %147
+  %297 = add nsw i64 %291, %219
+  %298 = sub nsw i64 %219, %291
+  %299 = add nsw i64 %297, %295
+  %300 = sub nsw i64 %295, %297
+  %301 = add nsw i64 %298, %296
+  %302 = sub nsw i64 %296, %298
+  %303 = lshr i64 %299, 31
+  %304 = and i64 %303, 4294967297
+  %305 = mul nuw i64 %304, 4294967295
+  %306 = add i64 %305, %299
+  %307 = xor i64 %306, %305
+  %308 = lshr i64 %301, 31
+  %309 = and i64 %308, 4294967297
+  %310 = mul nuw i64 %309, 4294967295
+  %311 = add i64 %310, %301
+  %312 = xor i64 %311, %310
+  %313 = lshr i64 %300, 31
+  %314 = and i64 %313, 4294967297
+  %315 = mul nuw i64 %314, 4294967295
+  %316 = add i64 %315, %300
+  %317 = xor i64 %316, %315
+  %318 = lshr i64 %302, 31
+  %319 = and i64 %318, 4294967297
+  %320 = mul nuw i64 %319, 4294967295
+  %321 = add i64 %320, %302
+  %322 = xor i64 %321, %320
+  %323 = add i64 %312, %307
+  %324 = add i64 %323, %317
+  %325 = add i64 %324, %322
+  %326 = add nsw i64 %149, %77
+  %327 = sub nsw i64 %77, %149
+  %328 = add nsw i64 %293, %221
+  %329 = sub nsw i64 %221, %293
+  %330 = add nsw i64 %328, %326
+  %331 = sub nsw i64 %326, %328
+  %332 = add nsw i64 %329, %327
+  %333 = sub nsw i64 %327, %329
+  %334 = lshr i64 %330, 31
+  %335 = and i64 %334, 4294967297
+  %336 = mul nuw i64 %335, 4294967295
+  %337 = add i64 %336, %330
+  %338 = xor i64 %337, %336
+  %339 = lshr i64 %332, 31
+  %340 = and i64 %339, 4294967297
+  %341 = mul nuw i64 %340, 4294967295
+  %342 = add i64 %341, %332
+  %343 = xor i64 %342, %341
+  %344 = lshr i64 %331, 31
+  %345 = and i64 %344, 4294967297
+  %346 = mul nuw i64 %345, 4294967295
+  %347 = add i64 %346, %331
+  %348 = xor i64 %347, %346
+  %349 = lshr i64 %333, 31
+  %350 = and i64 %349, 4294967297
+  %351 = mul nuw i64 %350, 4294967295
+  %352 = add i64 %351, %333
+  %353 = xor i64 %352, %351
+  %354 = add i64 %325, %343
+  %355 = add i64 %354, %338
+  %356 = add i64 %355, %348
+  %357 = add i64 %356, %353
+  %358 = add nsw i64 %148, %76
+  %359 = sub nsw i64 %76, %148
+  %360 = add nsw i64 %292, %220
+  %361 = sub nsw i64 %220, %292
+  %362 = add nsw i64 %360, %358
+  %363 = sub nsw i64 %358, %360
+  %364 = add nsw i64 %361, %359
+  %365 = sub nsw i64 %359, %361
+  %366 = lshr i64 %362, 31
+  %367 = and i64 %366, 4294967297
+  %368 = mul nuw i64 %367, 4294967295
+  %369 = add i64 %368, %362
+  %370 = xor i64 %369, %368
+  %371 = lshr i64 %364, 31
+  %372 = and i64 %371, 4294967297
+  %373 = mul nuw i64 %372, 4294967295
+  %374 = add i64 %373, %364
+  %375 = xor i64 %374, %373
+  %376 = lshr i64 %363, 31
+  %377 = and i64 %376, 4294967297
+  %378 = mul nuw i64 %377, 4294967295
+  %379 = add i64 %378, %363
+  %380 = xor i64 %379, %378
+  %381 = lshr i64 %365, 31
+  %382 = and i64 %381, 4294967297
+  %383 = mul nuw i64 %382, 4294967295
+  %384 = add i64 %383, %365
+  %385 = xor i64 %384, %383
+  %386 = add i64 %357, %375
+  %387 = add i64 %386, %370
+  %388 = add i64 %387, %380
+  %389 = add i64 %388, %385
+  %390 = add nsw i64 %150, %78
+  %391 = sub nsw i64 %78, %150
+  %392 = add nsw i64 %294, %222
+  %393 = sub nsw i64 %222, %294
+  %394 = add nsw i64 %392, %390
+  %395 = sub nsw i64 %390, %392
+  %396 = add nsw i64 %393, %391
+  %397 = sub nsw i64 %391, %393
+  %398 = lshr i64 %394, 31
+  %399 = and i64 %398, 4294967297
+  %400 = mul nuw i64 %399, 4294967295
+  %401 = add i64 %400, %394
+  %402 = xor i64 %401, %400
+  %403 = lshr i64 %396, 31
+  %404 = and i64 %403, 4294967297
+  %405 = mul nuw i64 %404, 4294967295
+  %406 = add i64 %405, %396
+  %407 = xor i64 %406, %405
+  %408 = lshr i64 %395, 31
+  %409 = and i64 %408, 4294967297
+  %410 = mul nuw i64 %409, 4294967295
+  %411 = add i64 %410, %395
+  %412 = xor i64 %411, %410
+  %413 = lshr i64 %397, 31
+  %414 = and i64 %413, 4294967297
+  %415 = mul nuw i64 %414, 4294967295
+  %416 = add i64 %415, %397
+  %417 = xor i64 %416, %415
+  %418 = add i64 %389, %407
+  %419 = add i64 %418, %402
+  %420 = add i64 %419, %412
+  %421 = add i64 %420, %417
+  %422 = and i64 %421, 4294967295
+  %423 = lshr i64 %421, 32
+  %424 = add nuw nsw i64 %422, %423
+  %425 = lshr i64 %424, 1
+  %426 = trunc nuw i64 %425 to i32
+  %427 = add nsw i32 %sum, %426
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
+  %428 = icmp samesign ult i64 %indvars.iv, 60
+  br i1 %428, label %.preheader, label %exit
+
+exit:
+  %.lcssa = phi i32 [ %427, %.preheader ]
+  ret i32 %.lcssa
+}
diff --git a/llvm/test/Transforms/LoopVectorize/X86/replicating-load-store-costs.ll b/llvm/test/Transforms/LoopVectorize/X86/replicating-load-store-costs.ll
index 35c58e0880402..bb005753856ae 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/replicating-load-store-costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/replicating-load-store-costs.ll
@@ -857,68 +857,32 @@ exit:
 define void @address_use_in_different_block(ptr noalias %dst, ptr %src.0, ptr %src.1, i32 %x) #0 {
 ; I64-LABEL: define void @address_use_in_different_block(
 ; I64-SAME: ptr noalias [[DST:%.*]], ptr [[SRC_0:%.*]], ptr [[SRC_1:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
-; I64-NEXT:  [[ENTRY:.*:]]
+; I64-NEXT:  [[ENTRY:.*]]:
 ; I64-NEXT:    [[X_POS:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 0)
 ; I64-NEXT:    [[OFFSET:%.*]] = zext i32 [[X_POS]] to i64
-; I64-NEXT:    br label %[[VECTOR_PH:.*]]
-; I64:       [[VECTOR_PH]]:
 ; I64-NEXT:    br label %[[VECTOR_BODY:.*]]
 ; I64:       [[VECTOR_BODY]]:
-; I64-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
-; I64-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 1
-; I64-NEXT:    [[TMP1:%.*]] = add i64 [[INDEX]], 2
-; I64-NEXT:    [[TMP2:%.*]] = add i64 [[INDEX]], 3
-; I64-NEXT:    [[TMP11:%.*]] = mul i64 [[INDEX]], [[OFFSET]]
-; I64-NEXT:    [[TMP12:%.*]] = mul i64 [[TMP0]], [[OFFSET]]
-; I64-NEXT:    [[TMP13:%.*]] = mul i64 [[TMP1]], [[OFFSET]]
+; I64-NEXT:    [[TMP2:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
 ; I64-NEXT:    [[TMP14:%.*]] = mul i64 [[TMP2]], [[OFFSET]]
-; I64-NEXT:    [[TMP19:%.*]] = getelementptr i32, ptr [[SRC_0]], i64 [[TMP11]]
-; I64-NEXT:    [[TMP20:%.*]] = getelementptr i32, ptr [[SRC_0]], i64 [[TMP12]]
-; I64-NEXT:    [[TMP21:%.*]] = getelementptr i32, ptr [[SRC_0]], i64 [[TMP13]]
 ; I64-NEXT:    [[TMP22:%.*]] = getelementptr i32, ptr [[SRC_0]], i64 [[TMP14]]
-; I64-NEXT:    [[TMP27:%.*]] = load i32, ptr [[TMP19]], align 4
-; I64-NEXT:    [[TMP28:%.*]] = load i32, ptr [[TMP20]], align 4
-; I64-NEXT:    [[TMP29:%.*]] = load i32, ptr [[TMP21]], align 4
 ; I64-NEXT:    [[TMP30:%.*]] = load i32, ptr [[TMP22]], align 4
-; I64-NEXT:    [[TMP35:%.*]] = sext i32 [[TMP27]] to i64
-; I64-NEXT:    [[TMP36:%.*]] = sext i32 [[TMP28]] to i64
-; I64-NEXT:    [[TMP37:%.*]] = sext i32 [[TMP29]] to i64
+; I64-NEXT:    [[C:%.*]] = icmp sgt i32 [[X]], 0
+; I64-NEXT:    br i1 [[C]], label %[[LOOP_LATCH]], label %[[THEN:.*]]
+; I64:       [[THEN]]:
+; I64-NEXT:    br label %[[LOOP_LATCH]]
+; I64:       [[LOOP_LATCH]]:
 ; I64-NEXT:    [[TMP38:%.*]] = sext i32 [[TMP30]] to i64
-; I64-NEXT:    [[TMP43:%.*]] = getelementptr double, ptr [[SRC_1]], i64 [[TMP35]]
-; I64-NEXT:    [[TMP44:%.*]] = getelementptr double, ptr [[SRC_1]], i64 [[TMP36]]
-; I64-NEXT:    [[TMP45:%.*]] = getelementptr double, ptr [[SRC_1]], i64 [[TMP37]]
 ; I64-NEXT:    [[TMP46:%.*]] = getelementptr double, ptr [[SRC_1]], i64 [[TMP38]]
-; I64-NEXT:    [[TMP51:%.*]] = getelementptr i8, ptr [[TMP43]], i64 -8
-; I64-NEXT:    [[TMP52:%.*]] = getelementptr i8, ptr [[TMP44]], i64 -8
-; I64-NEXT:    [[TMP53:%.*]] = getelementptr i8, ptr [[TMP45]], i64 -8
 ; I64-NEXT:    [[TMP54:%.*]] = getelementptr i8, ptr [[TMP46]], i64 -8
-; I64-NEXT:    [[TMP63:%.*]] = load double, ptr [[TMP51]], align 8
-; I64-NEXT:    [[TMP64:%.*]] = load double, ptr [[TMP52]], align 8
-; I64-NEXT:    [[TMP67:%.*]] = load double, ptr [[TMP53]], align 8
 ; I64-NEXT:    [[TMP68:%.*]] = load double, ptr [[TMP54]], align 8
-; I64-NEXT:    [[TMP31:%.*]] = insertelement <4 x double> poison, double [[TMP63]], i64 0
-; I64-NEXT:    [[TMP32:%.*]] = insertelement <4 x double> [[TMP31]], double [[TMP64]], i64 1
-; I64-NEXT:    [[TMP33:%.*]] = insertelement <4 x double> [[TMP32]], double [[TMP67]], i64 2
-; I64-NEXT:    [[TMP34:%.*]] = insertelement <4 x double> [[TMP33]], double [[TMP68]], i64 3
-; I64-NEXT:    [[TMP39:%.*]] = fsub <4 x double> zeroinitializer, [[TMP34]]
-; I64-NEXT:    [[TMP87:%.*]] = getelementptr double, ptr [[DST]], i64 [[TMP11]]
-; I64-NEXT:    [[TMP88:%.*]] = getelementptr double, ptr [[DST]], i64 [[TMP12]]
-; I64-NEXT:    [[TMP89:%.*]] = getelementptr double, ptr [[DST]], i64 [[TMP13]]
+; I64-NEXT:    [[TMP82:%.*]] = fsub double 0.000000e+00, [[TMP68]]
 ; I64-NEXT:    [[TMP90:%.*]] = getelementptr double, ptr [[DST]], i64 [[TMP14]]
-; I64-NEXT:    [[TMP78:%.*]] = extractelement <4 x double> [[TMP39]], i64 0
-; I64-NEXT:    store double [[TMP78]], ptr [[TMP87]], align 8
-; I64-NEXT:    [[TMP79:%.*]] = extractelement <4 x double> [[TMP39]], i64 1
-; I64-NEXT:    store double [[TMP79]], ptr [[TMP88]], align 8
-; I64-NEXT:    [[TMP81:%.*]] = extractelement <4 x double> [[TMP39]], i64 2
-; I64-NEXT:    store double [[TMP81]], ptr [[TMP89]], align 8
-; I64-NEXT:    [[TMP82:%.*]] = extractelement <4 x double> [[TMP39]], i64 3
 ; I64-NEXT:    store double [[TMP82]], ptr [[TMP90]], align 8
-; I64-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
-; I64-NEXT:    [[TMP47:%.*]] = icmp eq i64 [[INDEX_NEXT]], 100
-; I64-NEXT:    br i1 [[TMP47]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
-; I64:       [[MIDDLE_BLOCK]]:
-; I64-NEXT:    br label %[[SCALAR_PH:.*]]
+; I64-NEXT:    [[IV_NEXT]] = add i64 [[TMP2]], 1
+; I64-NEXT:    [[EC:%.*]] = icmp eq i64 [[TMP2]], 100
+; I64-NEXT:    br i1 [[EC]], label %[[SCALAR_PH:.*]], label %[[VECTOR_BODY]]
 ; I64:       [[SCALAR_PH]]:
+; I64-NEXT:    ret void
 ;
 ; I32-LABEL: define void @address_use_in_different_block(
 ; I32-SAME: ptr noalias [[DST:%.*]], ptr [[SRC_0:%.*]], ptr [[SRC_1:%.*]], i32 [[X:%.*]]) #[[ATTR0]] {
@@ -1142,7 +1106,7 @@ define void @replicated_load_wide_store_derived_iv_and(ptr noalias %src, ptr %ds
 ; I64-NEXT:    store <4 x float> [[TMP62]], ptr [[TMP64]], align 4
 ; I64-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
 ; I64-NEXT:    [[TMP65:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128
-; I64-NEXT:    br i1 [[TMP65]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
+; I64-NEXT:    br i1 [[TMP65]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
 ; I64:       [[MIDDLE_BLOCK]]:
 ; I64-NEXT:    br label %[[SCALAR_PH]]
 ; I64:       [[SCALAR_PH]]:
@@ -1256,7 +1220,7 @@ define void @replicated_load_wide_store_derived_iv_zext_and2(ptr noalias %dst, p
 ; I64-NEXT:    store <4 x float> [[TMP54]], ptr [[TMP56]], align 4
 ; I64-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
 ; I64-NEXT:    [[TMP57:%.*]] = icmp eq i64 [[INDEX_NEXT]], 128
-; I64-NEXT:    br i1 [[TMP57]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
+; I64-NEXT:    br i1 [[TMP57]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
 ; I64:       [[MIDDLE_BLOCK]]:
 ; I64-NEXT:    br label %[[SCALAR_PH]]
 ; I64:       [[SCALAR_PH]]:
@@ -1325,7 +1289,7 @@ define void @invariant_pred_store_sunk_out_of_loop(ptr noalias %dst, ptr noalias
 ; I64-NEXT:    [[TMP5]] = add <2 x i64> [[TMP3]], splat (i64 1)
 ; I64-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[IV]], 4
 ; I64-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
-; I64-NEXT:    br i1 [[TMP6]], label %[[IF_THEN:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
+; I64-NEXT:    br i1 [[TMP6]], label %[[IF_THEN:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
 ; I64:       [[IF_THEN]]:
 ; I64-NEXT:    [[BIN_RDX:%.*]] = add <2 x i64> [[TMP5]], [[TMP4]]
 ; I64-NEXT:    [[SUM_1:%.*]] = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> [[BIN_RDX]])



More information about the llvm-commits mailing list