[llvm] [NFC] [IndVarSimplify] add overflowing tests (PR #159877)

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 23 12:26:34 PDT 2025


https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/159877

>From 4a3cc7356d7c9801886268fe90a19a4a0f3cbbea Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Fri, 19 Sep 2025 16:37:52 -0700
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20ch?=
 =?UTF-8?q?anges=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4

[skip ci]
---
 .../IndVarSimplify/X86/overflow-intrinsics.ll | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index e678146c80af8..4a59e419369af 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -109,6 +109,37 @@ for.body:                                         ; preds = %entry, %cont
   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
 
+; CHECK: for.body:
+; CHECK-NOT: @llvm.usub.with.overflow.i32
+; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0
+  br i1 %1, label %trap, label %cont, !nosanitize !{}
+
+trap:                                             ; preds = %for.body
+  tail call void @llvm.trap(), !nosanitize !{}
+  unreachable, !nosanitize !{}
+
+cont:                                             ; preds = %for.body
+  %2 = extractvalue { i32, i1 } %0, 0
+  %cmp = icmp sgt i32 %2, 0
+  br i1 %cmp, label %for.body, label %for.cond.cleanup
+}
+
+define void @f_usub_overflow(ptr nocapture %a) {
+; CHECK-LABEL: @f_usub_overflow(
+entry:
+  br label %for.body
+
+for.cond.cleanup:                                 ; preds = %cont
+  ret void
+
+for.body:                                         ; preds = %entry, %cont
+  %i.04 = phi i32 [ 15, %entry ], [ %2, %cont ]
+  %idxprom = sext i32 %i.04 to i64
+  %arrayidx = getelementptr inbounds i8, ptr %a, i64 %idxprom
+  store i8 0, ptr %arrayidx, align 1
+  %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
+  %1 = extractvalue { i32, i1 } %0, 1
+
 ; It is theoretically possible to prove this, but SCEV cannot
 ; represent non-unsigned-wrapping subtraction operations.
 

>From ebdadaf8b6408c19d66f7a7e8e43146067ec03c0 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Fri, 19 Sep 2025 16:39:45 -0700
Subject: [PATCH 2/4] ixup

Created using spr 1.3.4
---
 llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index b5f8f9ece6809..8f8ea97132461 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -137,9 +137,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; It is theoretically possible to prove this, but SCEV cannot
-; represent non-unsigned-wrapping subtraction operations.
-
 ; CHECK: for.body:
 ; CHECK-NOT: @llvm.ssub.with.overflow.i32
 ; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0

>From 14cdd31f03fe9c206dcbb918c112936184d394a4 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Fri, 19 Sep 2025 16:40:34 -0700
Subject: [PATCH 3/4] fmt

Created using spr 1.3.4
---
 llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index 8f8ea97132461..6af959e47b12e 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -121,7 +121,6 @@ cont:                                             ; preds = %for.body
   br i1 %cmp, label %for.body, label %for.cond.cleanup
 }
 
-
 define void @f_ssub(ptr nocapture %a) {
 ; CHECK-LABEL: @f_ssub(
 entry:

>From a5934f6b401ce3cee936438db173c7fc676cece2 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Tue, 23 Sep 2025 12:26:19 -0700
Subject: [PATCH 4/4] UTC

Created using spr 1.3.4
---
 .../IndVarSimplify/X86/overflow-intrinsics.ll | 193 +++++++++++++++---
 1 file changed, 160 insertions(+), 33 deletions(-)

diff --git a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
index 6af959e47b12e..eda7e0c924355 100644
--- a/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
+++ b/llvm/test/Transforms/IndVarSimplify/X86/overflow-intrinsics.ll
@@ -1,10 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt -S -passes=indvars < %s | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
 define void @f_sadd(ptr %a) {
-; CHECK-LABEL: @f_sadd(
+; CHECK-LABEL: define void @f_sadd(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0:![0-9]+]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 16
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -18,9 +37,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK: for.body:
-; CHECK-NOT: @llvm.sadd.with.overflow
-; CHECK:  br i1 false, label %trap, label %cont, !nosanitize !0
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -34,7 +50,25 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_sadd_overflow(ptr %a) {
-; CHECK-LABEL: @f_sadd_overflow(
+; CHECK-LABEL: define void @f_sadd_overflow(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 2147483645, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV]], 2147483647
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -48,8 +82,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK: cont:
-; CHECK: br i1 true, label %for.body, label %for.cond.cleanup
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -63,7 +95,25 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_uadd(ptr %a) {
-; CHECK-LABEL: @f_uadd(
+; CHECK-LABEL: define void @f_uadd(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV_NEXT]], 16
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -77,9 +127,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK: for.body:
-; CHECK-NOT: @llvm.uadd.with.overflow
-; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -93,7 +140,25 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_uadd_overflow(ptr %a) {
-; CHECK-LABEL: @f_uadd_overflow(
+; CHECK-LABEL: define void @f_uadd_overflow(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ -6, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV]], -1
+; CHECK-NEXT:    br i1 [[EXITCOND]], label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], 1
+; CHECK-NEXT:    br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -107,8 +172,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK: cont:
-; CHECK: br i1 true, label %for.body, label %for.cond.cleanup
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -122,7 +185,25 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_ssub(ptr nocapture %a) {
-; CHECK-LABEL: @f_ssub(
+; CHECK-LABEL: define void @f_ssub(
+; CHECK-SAME: ptr captures(none) [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 15, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
+; CHECK-NEXT:    br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i64 [[INDVARS_IV_NEXT]], -1
+; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -136,9 +217,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK: for.body:
-; CHECK-NOT: @llvm.ssub.with.overflow.i32
-; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -152,7 +230,27 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_ssub_overflow(ptr nocapture %a) {
-; CHECK-LABEL: @f_ssub_overflow(
+; CHECK-LABEL: define void @f_ssub_overflow(
+; CHECK-SAME: ptr captures(none) [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ -2147483642, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[TMP0]], i32 1)
+; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
+; CHECK-NEXT:    br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -166,10 +264,6 @@ for.body:                                         ; preds = %entry, %cont
   store i8 0, ptr %arrayidx, align 1
   %0 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
-; CHECK:  [[COND:%[^ ]+]] = extractvalue { i32, i1 } %1, 1
-; CHECK-NEXT:  br i1 [[COND]], label %trap, label %cont, !nosanitize !0
-; CHECK: cont:
-; CHECK: br i1 true, label %for.body, label %for.cond.cleanup
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -183,7 +277,25 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_usub(ptr nocapture %a) {
-; CHECK-LABEL: @f_usub(
+; CHECK-LABEL: define void @f_usub(
+; CHECK-SAME: ptr captures(none) [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 15, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
+; CHECK-NEXT:    br i1 false, label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i64 [[INDVARS_IV_NEXT]], 0
+; CHECK-NEXT:    br i1 [[CMP]], label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -198,9 +310,6 @@ for.body:                                         ; preds = %entry, %cont
   %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %i.04, i32 1)
   %1 = extractvalue { i32, i1 } %0, 1
 
-; CHECK: for.body:
-; CHECK-NOT: @llvm.usub.with.overflow.i32
-; CHECK: br i1 false, label %trap, label %cont, !nosanitize !0
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -214,7 +323,27 @@ cont:                                             ; preds = %for.body
 }
 
 define void @f_usub_overflow(ptr nocapture %a) {
-; CHECK-LABEL: @f_usub_overflow(
+; CHECK-LABEL: define void @f_usub_overflow(
+; CHECK-SAME: ptr captures(none) [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*]]:
+; CHECK-NEXT:    br label %[[FOR_BODY:.*]]
+; CHECK:       [[FOR_COND_CLEANUP:.*]]:
+; CHECK-NEXT:    ret void
+; CHECK:       [[FOR_BODY]]:
+; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[CONT:.*]] ], [ 15, %[[ENTRY]] ]
+; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[INDVARS_IV]]
+; CHECK-NEXT:    store i8 0, ptr [[ARRAYIDX]], align 1
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc nuw nsw i64 [[INDVARS_IV]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[TMP0]], i32 1)
+; CHECK-NEXT:    [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1
+; CHECK-NEXT:    br i1 [[TMP2]], label %[[TRAP:.*]], label %[[CONT]], !nosanitize [[META0]]
+; CHECK:       [[TRAP]]:
+; CHECK-NEXT:    tail call void @llvm.trap(), !nosanitize [[META0]]
+; CHECK-NEXT:    unreachable, !nosanitize [[META0]]
+; CHECK:       [[CONT]]:
+; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
+; CHECK-NEXT:    br i1 true, label %[[FOR_BODY]], label %[[FOR_COND_CLEANUP]]
+;
 entry:
   br label %for.body
 
@@ -232,11 +361,6 @@ for.body:                                         ; preds = %entry, %cont
 ; It is theoretically possible to prove this, but SCEV cannot
 ; represent non-unsigned-wrapping subtraction operations.
 
-; CHECK: for.body:
-; CHECK:  [[COND:%[^ ]+]] = extractvalue { i32, i1 } %1, 1
-; CHECK-NEXT:  br i1 [[COND]], label %trap, label %cont, !nosanitize !0
-; CHECK: cont:
-; CHECK: br i1 true, label %for.body, label %for.cond.cleanup
   br i1 %1, label %trap, label %cont, !nosanitize !{}
 
 trap:                                             ; preds = %for.body
@@ -257,3 +381,6 @@ declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
 
 declare void @llvm.trap() #2
+;.
+; CHECK: [[META0]] = !{}
+;.



More information about the llvm-commits mailing list