[llvm] Revert "[LoopVectorize] Support vectorization of overflow intrinsics" (PR #179819)

via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 4 15:49:32 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-analysis

Author: Alexander Kornienko (alexfh)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->174835, which causes clang crashes.

See https://github.com/llvm/llvm-project/pull/174835#issuecomment-3844233831 and later comments for the test case and initial investigation.

---

Patch is 35.12 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/179819.diff


5 Files Affected:

- (modified) llvm/lib/Analysis/VectorUtils.cpp (+9-6) 
- (modified) llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp (+1-6) 
- (modified) llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll (+1-73) 
- (modified) llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll (+1-469) 
- (modified) llvm/test/Transforms/LoopVectorize/struct-return.ll (+15-18) 


``````````diff
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index d4083c49626fe..79723c9815445 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -65,12 +65,6 @@ bool llvm::isTriviallyVectorizable(Intrinsic::ID ID) {
   case Intrinsic::smul_fix_sat:
   case Intrinsic::umul_fix:
   case Intrinsic::umul_fix_sat:
-  case Intrinsic::uadd_with_overflow:
-  case Intrinsic::sadd_with_overflow:
-  case Intrinsic::usub_with_overflow:
-  case Intrinsic::ssub_with_overflow:
-  case Intrinsic::umul_with_overflow:
-  case Intrinsic::smul_with_overflow:
   case Intrinsic::sqrt: // Begin floating-point.
   case Intrinsic::asin:
   case Intrinsic::acos:
@@ -136,6 +130,15 @@ bool llvm::isTriviallyScalarizable(Intrinsic::ID ID,
   if (TTI && Intrinsic::isTargetIntrinsic(ID))
     return TTI->isTargetIntrinsicTriviallyScalarizable(ID);
 
+  switch (ID) {
+  case Intrinsic::uadd_with_overflow:
+  case Intrinsic::sadd_with_overflow:
+  case Intrinsic::ssub_with_overflow:
+  case Intrinsic::usub_with_overflow:
+  case Intrinsic::umul_with_overflow:
+  case Intrinsic::smul_with_overflow:
+    return true;
+  }
   return false;
 }
 
diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index fa395e7d07531..898507d11a46b 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -1834,12 +1834,7 @@ void VPWidenIntrinsicRecipe::execute(VPTransformState &State) {
   if (isVectorIntrinsicWithOverloadTypeAtArg(VectorIntrinsicID, -1,
                                              State.TTI)) {
     Type *RetTy = toVectorizedTy(getResultType(), State.VF);
-    ArrayRef<Type *> ContainedTys = getContainedTypes(RetTy);
-    for (auto [Idx, Ty] : enumerate(ContainedTys)) {
-      if (isVectorIntrinsicWithStructReturnOverloadAtField(VectorIntrinsicID,
-                                                           Idx, State.TTI))
-        TysForDecl.push_back(Ty);
-    }
+    append_range(TysForDecl, getContainedTypes(RetTy));
   }
   SmallVector<Value *, 4> Args;
   for (const auto &I : enumerate(operands())) {
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll b/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
index 55994ad9a98f8..66247a4f8100e 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/multiple-result-intrinsics.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|modf|extractvalue|store|with\.overflow)" --version 5
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|modf|extractvalue|store)" --version 5
 ; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve < %s -S -o - -debug-only=loop-vectorize 2>%t.1 | FileCheck %s --check-prefix=CHECK
 ; RUN: opt -passes=loop-vectorize -mtriple=aarch64-gnu-linux -mcpu=neoverse-v1 -mattr=+sve -vector-library=ArmPL < %s -S -o - -debug-only=loop-vectorize 2>%t.2 | FileCheck %s --check-prefix=CHECK-ARMPL
 ; RUN: FileCheck --input-file=%t.1 --check-prefix=CHECK-COST %s
@@ -526,75 +526,3 @@ for.body:
 exit:
   ret void
 }
-
-; CHECK-COST-LABEL: sadd_with_overflow_i32
-; CHECK-COST: LV: Found an estimated cost of 1 for VF 1 For instruction:   %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-; CHECK-COST: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-
-; CHECK-COST-ARMPL-LABEL: sadd_with_overflow_i32
-; CHECK-COST-ARMPL: LV: Found an estimated cost of 1 for VF 1 For instruction:   %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-; CHECK-COST-ARMPL: Cost of 4 for VF 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 7 for VF 8: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 13 for VF 16: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of Invalid for VF vscale x 1: REPLICATE ir<%call> = call @llvm.sadd.with.overflow.i32(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 2: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-; CHECK-COST-ARMPL: Cost of 4 for VF vscale x 4: WIDEN-INTRINSIC ir<%call> = call llvm.sadd.with.overflow(ir<%val_a>, ir<%val_b>)
-
-define void @sadd_with_overflow_i32(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @sadd_with_overflow_i32(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) #[[ATTR0]] {
-; CHECK:  [[ENTRY:.*:]]
-; CHECK:  [[VECTOR_PH:.*:]]
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:    [[TMP9:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i1> } @llvm.sadd.with.overflow.nxv4i32(<vscale x 4 x i32> [[WIDE_MASKED_LOAD:%.*]], <vscale x 4 x i32> [[WIDE_MASKED_LOAD1:%.*]])
-; CHECK:    [[TMP10:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i1> } [[TMP9]], 0
-; CHECK:    [[TMP11:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i1> } [[TMP9]], 1
-; CHECK:    call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> [[TMP10]], ptr align 4 [[TMP13:%.*]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK:%.*]])
-; CHECK:    call void @llvm.masked.store.nxv4i8.p0(<vscale x 4 x i8> [[TMP12:%.*]], ptr align 1 [[TMP14:%.*]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK]])
-; CHECK:  [[MIDDLE_BLOCK:.*:]]
-; CHECK:  [[EXIT:.*:]]
-;
-; CHECK-ARMPL-LABEL: define void @sadd_with_overflow_i32(
-; CHECK-ARMPL-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) #[[ATTR0]] {
-; CHECK-ARMPL:  [[ENTRY:.*:]]
-; CHECK-ARMPL:  [[VECTOR_PH:.*:]]
-; CHECK-ARMPL:  [[VECTOR_BODY:.*:]]
-; CHECK-ARMPL:    [[TMP9:%.*]] = call { <vscale x 4 x i32>, <vscale x 4 x i1> } @llvm.sadd.with.overflow.nxv4i32(<vscale x 4 x i32> [[WIDE_MASKED_LOAD:%.*]], <vscale x 4 x i32> [[WIDE_MASKED_LOAD1:%.*]])
-; CHECK-ARMPL:    [[TMP10:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i1> } [[TMP9]], 0
-; CHECK-ARMPL:    [[TMP11:%.*]] = extractvalue { <vscale x 4 x i32>, <vscale x 4 x i1> } [[TMP9]], 1
-; CHECK-ARMPL:    call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> [[TMP10]], ptr align 4 [[TMP13:%.*]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK:%.*]])
-; CHECK-ARMPL:    call void @llvm.masked.store.nxv4i8.p0(<vscale x 4 x i8> [[TMP12:%.*]], ptr align 1 [[TMP14:%.*]], <vscale x 4 x i1> [[ACTIVE_LANE_MASK]])
-; CHECK-ARMPL:  [[MIDDLE_BLOCK:.*:]]
-; CHECK-ARMPL:  [[EXIT:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i32, ptr %in_a, i64 %iv
-  %val_a = load i32, ptr %arrayidx_a, align 4
-  %arrayidx_b = getelementptr inbounds i32, ptr %in_b, i64 %iv
-  %val_b = load i32, ptr %arrayidx_b, align 4
-  %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-  %result = extractvalue { i32, i1 } %call, 0
-  %overflow = extractvalue { i32, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i32, ptr %out_result, i64 %iv
-  store i32 %result, ptr %arrayidx_result, align 4
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
diff --git a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
index f64d43adecfb8..c6fcbed983d3c 100644
--- a/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
+++ b/llvm/test/Transforms/LoopVectorize/multiple-result-intrinsics.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|frexp|modf|extract|store|with\.overflow)" --version 5
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --filter "(:|sincos|frexp|modf|extract|store)" --version 5
 ; RUN: opt -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=2 < %s -S -o - | FileCheck %s
 
 define void @sincos_f32(ptr noalias %in, ptr noalias writeonly %out_a, ptr noalias writeonly %out_b) {
@@ -348,471 +348,3 @@ for.body:
 exit:
   ret void
 }
-
-define void @uadd_with_overflow_i32(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @uadd_with_overflow_i32(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.uadd.with.overflow.v2i32(<2 x i32> [[WIDE_LOAD:%.*]], <2 x i32> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i32> [[TMP5]], ptr [[TMP9:%.*]], align 4
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i32, ptr %in_a, i64 %iv
-  %val_a = load i32, ptr %arrayidx_a, align 4
-  %arrayidx_b = getelementptr inbounds i32, ptr %in_b, i64 %iv
-  %val_b = load i32, ptr %arrayidx_b, align 4
-  %call = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-  %result = extractvalue { i32, i1 } %call, 0
-  %overflow = extractvalue { i32, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i32, ptr %out_result, i64 %iv
-  store i32 %result, ptr %arrayidx_result, align 4
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
-
-define void @uadd_with_overflow_i64(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @uadd_with_overflow_i64(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i64>, <2 x i1> } @llvm.uadd.with.overflow.v2i64(<2 x i64> [[WIDE_LOAD:%.*]], <2 x i64> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i64> [[TMP5]], ptr [[TMP9:%.*]], align 8
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i64, ptr %in_a, i64 %iv
-  %val_a = load i64, ptr %arrayidx_a, align 8
-  %arrayidx_b = getelementptr inbounds i64, ptr %in_b, i64 %iv
-  %val_b = load i64, ptr %arrayidx_b, align 8
-  %call = tail call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 %val_a, i64 %val_b)
-  %result = extractvalue { i64, i1 } %call, 0
-  %overflow = extractvalue { i64, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i64, ptr %out_result, i64 %iv
-  store i64 %result, ptr %arrayidx_result, align 8
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
-
-define void @sadd_with_overflow_i32(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @sadd_with_overflow_i32(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.sadd.with.overflow.v2i32(<2 x i32> [[WIDE_LOAD:%.*]], <2 x i32> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i32> [[TMP5]], ptr [[TMP9:%.*]], align 4
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i32, ptr %in_a, i64 %iv
-  %val_a = load i32, ptr %arrayidx_a, align 4
-  %arrayidx_b = getelementptr inbounds i32, ptr %in_b, i64 %iv
-  %val_b = load i32, ptr %arrayidx_b, align 4
-  %call = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %val_a, i32 %val_b)
-  %result = extractvalue { i32, i1 } %call, 0
-  %overflow = extractvalue { i32, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i32, ptr %out_result, i64 %iv
-  store i32 %result, ptr %arrayidx_result, align 4
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
-
-define void @sadd_with_overflow_i64(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @sadd_with_overflow_i64(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i64>, <2 x i1> } @llvm.sadd.with.overflow.v2i64(<2 x i64> [[WIDE_LOAD:%.*]], <2 x i64> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i64> [[TMP5]], ptr [[TMP9:%.*]], align 8
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i64, ptr %in_a, i64 %iv
-  %val_a = load i64, ptr %arrayidx_a, align 8
-  %arrayidx_b = getelementptr inbounds i64, ptr %in_b, i64 %iv
-  %val_b = load i64, ptr %arrayidx_b, align 8
-  %call = tail call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %val_a, i64 %val_b)
-  %result = extractvalue { i64, i1 } %call, 0
-  %overflow = extractvalue { i64, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i64, ptr %out_result, i64 %iv
-  store i64 %result, ptr %arrayidx_result, align 8
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
-
-define void @usub_with_overflow_i32(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @usub_with_overflow_i32(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i32>, <2 x i1> } @llvm.usub.with.overflow.v2i32(<2 x i32> [[WIDE_LOAD:%.*]], <2 x i32> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i32>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i32> [[TMP5]], ptr [[TMP9:%.*]], align 4
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i32, ptr %in_a, i64 %iv
-  %val_a = load i32, ptr %arrayidx_a, align 4
-  %arrayidx_b = getelementptr inbounds i32, ptr %in_b, i64 %iv
-  %val_b = load i32, ptr %arrayidx_b, align 4
-  %call = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %val_a, i32 %val_b)
-  %result = extractvalue { i32, i1 } %call, 0
-  %overflow = extractvalue { i32, i1 } %call, 1
-  %zext_overflow = zext i1 %overflow to i8
-  %arrayidx_result = getelementptr inbounds i32, ptr %out_result, i64 %iv
-  store i32 %result, ptr %arrayidx_result, align 4
-  %arrayidx_overflow = getelementptr inbounds i8, ptr %out_overflow, i64 %iv
-  store i8 %zext_overflow, ptr %arrayidx_overflow, align 1
-  %iv.next = add nuw nsw i64 %iv, 1
-  %exitcond.not = icmp eq i64 %iv.next, 1024
-  br i1 %exitcond.not, label %exit, label %for.body
-
-exit:
-  ret void
-}
-
-define void @usub_with_overflow_i64(ptr noalias %in_a, ptr noalias %in_b, ptr noalias writeonly %out_result, ptr noalias writeonly %out_overflow) {
-; CHECK-LABEL: define void @usub_with_overflow_i64(
-; CHECK-SAME: ptr noalias [[IN_A:%.*]], ptr noalias [[IN_B:%.*]], ptr noalias writeonly [[OUT_RESULT:%.*]], ptr noalias writeonly [[OUT_OVERFLOW:%.*]]) {
-; CHECK:  [[VECTOR_BODY:.*:]]
-; CHECK:  [[FOR_BODY:.*:]]
-; CHECK:  [[VECTOR_BODY1:.*:]]
-; CHECK:    [[TMP4:%.*]] = call { <2 x i64>, <2 x i1> } @llvm.usub.with.overflow.v2i64(<2 x i64> [[WIDE_LOAD:%.*]], <2 x i64> [[WIDE_LOAD1:%.*]])
-; CHECK:    [[TMP5:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 0
-; CHECK:    [[TMP6:%.*]] = extractvalue { <2 x i64>, <2 x i1> } [[TMP4]], 1
-; CHECK:    store <2 x i64> [[TMP5]], ptr [[TMP9:%.*]], align 8
-; CHECK:    store <2 x i8> [[TMP8:%.*]], ptr [[TMP7:%.*]], align 1
-; CHECK:  [[EXIT:.*:]]
-; CHECK:  [[EXIT1:.*:]]
-;
-entry:
-  br label %for.body
-
-for.body:
-  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
-  %arrayidx_a = getelementptr inbounds i64, ptr %in_a, i64 %iv
-  %val_a = load i64, ptr %arrayidx_a, align 8
-  %arrayidx_b = getelementptr inbounds i64, p...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/179819


More information about the llvm-commits mailing list