[llvm] f1483ea - [PhaseOrdering] Add more tests for expanding ptr SCEVs (NFC) (#211360)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 22 13:53:01 PDT 2026
Author: Florian Hahn
Date: 2026-07-22T21:52:57+01:00
New Revision: f1483ea484bafdf5e7ec6f17e94f7200256aa0e5
URL: https://github.com/llvm/llvm-project/commit/f1483ea484bafdf5e7ec6f17e94f7200256aa0e5
DIFF: https://github.com/llvm/llvm-project/commit/f1483ea484bafdf5e7ec6f17e94f7200256aa0e5.diff
LOG: [PhaseOrdering] Add more tests for expanding ptr SCEVs (NFC) (#211360)
Add more test cases requiring pointer-based SCEVs for
https://github.com/llvm/llvm-project/pull/180244.
Added:
llvm/test/Transforms/IndVarSimplify/AArch64/ptrtoaddr-ptrtoint.ll
llvm/test/Transforms/IndVarSimplify/X86/ptrtoaddr-narrow-pointer.ll
llvm/test/Transforms/LoopStrengthReduce/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
llvm/test/Transforms/PhaseOrdering/X86/ptrtoaddr-ptrtoint.ll
Modified:
llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
Removed:
llvm/test/Transforms/IndVarSimplify/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
################################################################################
diff --git a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
index 2b07c944eb1d1..4863477fbd977 100644
--- a/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
+++ b/llvm/test/Analysis/ScalarEvolution/ptrtoint.ll
@@ -684,3 +684,58 @@ bb13: ; preds = %bb10, %bb8
bb14: ; preds = %bb
ret void
}
+
+define i64 @ptrtoint_signbits(i1 %c) {
+; CHECK-LABEL: 'ptrtoint_signbits'
+; CHECK-NEXT: Classifying expressions for: @ptrtoint_signbits
+; CHECK-NEXT: %p = select i1 %c, ptr null, ptr inttoptr (i64 -1 to ptr)
+; CHECK-NEXT: --> %p U: [-1,1) S: [-1,1)
+; CHECK-NEXT: %a = ptrtoint ptr %p to i64
+; CHECK-NEXT: --> %a U: full-set S: full-set
+; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_signbits
+;
+ %p = select i1 %c, ptr null, ptr inttoptr (i64 -1 to ptr)
+ %a = ptrtoint ptr %p to i64
+ ret i64 %a
+}
+
+define void @ptrtoint_iv_start(ptr %arg, ptr %dst) {
+; CHECK-LABEL: 'ptrtoint_iv_start_no_cancel'
+; CHECK-NEXT: Classifying expressions for: @ptrtoint_iv_start_no_cancel
+; CHECK-NEXT: %start = ptrtoint ptr %arg to i64
+; CHECK-NEXT: --> %start U: full-set S: full-set
+; CHECK-NEXT: %p = phi ptr [ %arg, %entry ], [ %p.next, %loop ]
+; CHECK-NEXT: --> {%arg,+,8}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %pi = phi i64 [ %start, %entry ], [ %pi.next, %loop ]
+; CHECK-NEXT: --> {%start,+,8}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %cur = ptrtoint ptr %p to i64
+; CHECK-NEXT: --> {(ptrtoaddr ptr %arg to i64),+,8}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %off = sub i64 %cur, %pi
+; CHECK-NEXT: --> ((-1 * %start) + (ptrtoaddr ptr %arg to i64)) U: full-set S: full-set Exits: ((-1 * %start) + (ptrtoaddr ptr %arg to i64)) LoopDispositions: { %loop: Invariant }
+; CHECK-NEXT: %p.next = getelementptr i8, ptr %p, i64 8
+; CHECK-NEXT: --> {(8 + %arg),+,8}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: %pi.next = add i64 %pi, 8
+; CHECK-NEXT: --> {(8 + %start),+,8}<%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }
+; CHECK-NEXT: Determining loop execution counts for: @ptrtoint_iv_start_no_cancel
+; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
+; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
+;
+entry:
+ %start = ptrtoint ptr %arg to i64
+ br label %loop
+
+loop:
+ %p = phi ptr [ %arg, %entry ], [ %p.next, %loop ]
+ %pi = phi i64 [ %start, %entry ], [ %pi.next, %loop ]
+ %cur = ptrtoint ptr %p to i64
+ %off = sub i64 %cur, %pi
+ store i64 %off, ptr %dst, align 8
+ %p.next = getelementptr i8, ptr %p, i64 8
+ %pi.next = add i64 %pi, 8
+ %ec = icmp eq i64 %off, 80
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret void
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll b/llvm/test/Transforms/IndVarSimplify/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
deleted file mode 100644
index 30afcf6237067..0000000000000
--- a/llvm/test/Transforms/IndVarSimplify/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
+++ /dev/null
@@ -1,46 +0,0 @@
-; RUN: opt -passes='indvars' -S %s | FileCheck %s
-
-target triple = "arm64-apple-macosx"
-
-define i64 @count_then_convert(ptr %end) {
-; CHECK-LABEL: @count_then_convert(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[END1:%.*]] = ptrtoint ptr [[END:%.*]] to i64
-; CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq ptr [[END]], null
-; CHECK-NEXT: br i1 [[ISEMPTY]], label [[EXIT:%.*]], label [[BODY_PH:%.*]]
-; CHECK: body.ph:
-; CHECK-NEXT: br label [[BODY:%.*]]
-; CHECK: body:
-; CHECK-NEXT: br i1 true, label [[EXIT_LOOPEXIT:%.*]], label [[BODY]]
-; CHECK: exit.loopexit:
-; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[END1]], -8
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 3
-; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
-; CHECK-NEXT: br label [[EXIT]]
-; CHECK: exit:
-; CHECK-NEXT: [[CNT:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[TMP2]], [[EXIT_LOOPEXIT]] ]
-; CHECK-NEXT: [[ENDI:%.*]] = ptrtoint ptr [[END]] to i64
-; CHECK-NEXT: [[R:%.*]] = or i64 [[CNT]], [[ENDI]]
-; CHECK-NEXT: ret i64 [[R]]
-;
-entry:
- %isempty = icmp eq ptr %end, null
- br i1 %isempty, label %exit, label %body.ph
-
-body.ph:
- br label %body
-
-body:
- %p = phi ptr [ null, %body.ph ], [ %pn, %body ]
- %n = phi i64 [ 0, %body.ph ], [ %nn, %body ]
- %nn = add i64 %n, 1
- %pn = getelementptr inbounds nuw i8, ptr %p, i64 8
- %done = icmp eq ptr %pn, %end
- br i1 %done, label %exit, label %body
-
-exit:
- %cnt = phi i64 [ 0, %entry ], [ %nn, %body ]
- %endi = ptrtoint ptr %end to i64
- %r = or i64 %cnt, %endi
- ret i64 %r
-}
diff --git a/llvm/test/Transforms/IndVarSimplify/AArch64/ptrtoaddr-ptrtoint.ll b/llvm/test/Transforms/IndVarSimplify/AArch64/ptrtoaddr-ptrtoint.ll
new file mode 100644
index 0000000000000..fee21dc0a9300
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/AArch64/ptrtoaddr-ptrtoint.ll
@@ -0,0 +1,106 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='indvars' -S %s | FileCheck %s
+
+target triple = "arm64-apple-macosx"
+
+define i64 @count_then_convert(ptr %end) {
+; CHECK-LABEL: define i64 @count_then_convert(
+; CHECK-SAME: ptr [[END:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[END1:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq ptr [[END]], null
+; CHECK-NEXT: br i1 [[ISEMPTY]], label %[[EXIT:.*]], label %[[BODY_PH:.*]]
+; CHECK: [[BODY_PH]]:
+; CHECK-NEXT: br label %[[BODY:.*]]
+; CHECK: [[BODY]]:
+; CHECK-NEXT: br i1 true, label %[[EXIT_LOOPEXIT:.*]], label %[[BODY]]
+; CHECK: [[EXIT_LOOPEXIT]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[END1]], -8
+; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 3
+; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[CNT:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[TMP2]], %[[EXIT_LOOPEXIT]] ]
+; CHECK-NEXT: [[ENDI:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT: [[R:%.*]] = or i64 [[CNT]], [[ENDI]]
+; CHECK-NEXT: ret i64 [[R]]
+;
+entry:
+ %isempty = icmp eq ptr %end, null
+ br i1 %isempty, label %exit, label %body.ph
+
+body.ph:
+ br label %body
+
+body:
+ %p = phi ptr [ null, %body.ph ], [ %pn, %body ]
+ %n = phi i64 [ 0, %body.ph ], [ %nn, %body ]
+ %nn = add i64 %n, 1
+ %pn = getelementptr inbounds nuw i8, ptr %p, i64 8
+ %done = icmp eq ptr %pn, %end
+ br i1 %done, label %exit, label %body
+
+exit:
+ %cnt = phi i64 [ 0, %entry ], [ %nn, %body ]
+ %endi = ptrtoint ptr %end to i64
+ %r = or i64 %cnt, %endi
+ ret i64 %r
+}
+
+define i64 @ptrtoint_sub_in_exit(ptr %start, ptr %bound) {
+; CHECK-LABEL: define i64 @ptrtoint_sub_in_exit(
+; CHECK-SAME: ptr [[START:%.*]], ptr [[BOUND:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[START3:%.*]] = ptrtoint ptr [[START]] to i64
+; CHECK-NEXT: [[BOUND2:%.*]] = ptrtoint ptr [[BOUND]] to i64
+; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[BOUND2]], [[START3]]
+; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[START]], i64 [[TMP0]]
+; CHECK-NEXT: br label %[[BODY:.*]]
+; CHECK: [[BODY]]:
+; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[START]], %[[ENTRY]] ], [ [[PN:%.*]], %[[LATCH:.*]] ]
+; CHECK-NEXT: [[C:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT: [[ISC:%.*]] = icmp slt i8 [[C]], -64
+; CHECK-NEXT: br i1 [[ISC]], label %[[LATCH]], label %[[EXIT_BYTE:.*]]
+; CHECK: [[LATCH]]:
+; CHECK-NEXT: [[PN]] = getelementptr inbounds i8, ptr [[P]], i64 -1
+; CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[PN]], [[BOUND]]
+; CHECK-NEXT: br i1 [[DONE]], label %[[EXIT_BOUND:.*]], label %[[BODY]]
+; CHECK: [[EXIT_BYTE]]:
+; CHECK-NEXT: [[P_LCSSA:%.*]] = phi ptr [ [[P]], %[[BODY]] ]
+; CHECK-NEXT: br label %[[EXIT:.*]]
+; CHECK: [[EXIT_BOUND]]:
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[FINAL:%.*]] = phi ptr [ [[P_LCSSA]], %[[EXIT_BYTE]] ], [ [[SCEVGEP]], %[[EXIT_BOUND]] ]
+; CHECK-NEXT: [[FI:%.*]] = ptrtoint ptr [[FINAL]] to i64
+; CHECK-NEXT: [[BI:%.*]] = ptrtoint ptr [[BOUND]] to i64
+; CHECK-NEXT: [[LEN:%.*]] = sub i64 [[FI]], [[BI]]
+; CHECK-NEXT: ret i64 [[LEN]]
+;
+entry:
+ br label %body
+
+body:
+ %p = phi ptr [ %start, %entry ], [ %pn, %latch ]
+ %c = load i8, ptr %p, align 1
+ %isc = icmp slt i8 %c, -64
+ br i1 %isc, label %latch, label %exit.byte
+
+latch:
+ %pn = getelementptr inbounds i8, ptr %p, i64 -1
+ %done = icmp eq ptr %pn, %bound
+ br i1 %done, label %exit.bound, label %body
+
+exit.byte:
+ br label %exit
+
+exit.bound:
+ br label %exit
+
+exit:
+ %final = phi ptr [ %p, %exit.byte ], [ %pn, %exit.bound ]
+ %fi = ptrtoint ptr %final to i64
+ %bi = ptrtoint ptr %bound to i64
+ %len = sub i64 %fi, %bi
+ ret i64 %len
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/X86/ptrtoaddr-narrow-pointer.ll b/llvm/test/Transforms/IndVarSimplify/X86/ptrtoaddr-narrow-pointer.ll
new file mode 100644
index 0000000000000..0019e7b1eea18
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/X86/ptrtoaddr-narrow-pointer.ll
@@ -0,0 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='indvars' -S %s | FileCheck %s
+
+target datalayout = "e-p:64:64-p1:64:64:64:32"
+target triple = "x86_64-unknown-linux"
+
+define ptr addrspace(1) @exit_value_narrow_address(ptr addrspace(1) %start, ptr addrspace(1) %end) {
+; CHECK-LABEL: define ptr addrspace(1) @exit_value_narrow_address(
+; CHECK-SAME: ptr addrspace(1) [[START:%.*]], ptr addrspace(1) [[END:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[PRE:%.*]] = icmp ult ptr addrspace(1) [[START]], [[END]]
+; CHECK-NEXT: br i1 [[PRE]], label %[[LOOP_PREHEADER:.*]], label %[[EXIT:.*]]
+; CHECK: [[LOOP_PREHEADER]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[P:%.*]] = phi ptr addrspace(1) [ [[P_NEXT:%.*]], %[[LOOP]] ], [ [[START]], %[[LOOP_PREHEADER]] ]
+; CHECK-NEXT: [[P_NEXT]] = getelementptr inbounds i8, ptr addrspace(1) [[P]], i64 1
+; CHECK-NEXT: [[C:%.*]] = icmp ult ptr addrspace(1) [[P_NEXT]], [[END]]
+; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT_LOOPEXIT:.*]]
+; CHECK: [[EXIT_LOOPEXIT]]:
+; CHECK-NEXT: [[P_NEXT_LCSSA:%.*]] = phi ptr addrspace(1) [ [[P_NEXT]], %[[LOOP]] ]
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[RES:%.*]] = phi ptr addrspace(1) [ [[START]], %[[ENTRY]] ], [ [[P_NEXT_LCSSA]], %[[EXIT_LOOPEXIT]] ]
+; CHECK-NEXT: ret ptr addrspace(1) [[RES]]
+;
+entry:
+ %pre = icmp ult ptr addrspace(1) %start, %end
+ br i1 %pre, label %loop, label %exit
+
+loop:
+ %p = phi ptr addrspace(1) [ %start, %entry ], [ %p.next, %loop ]
+ %p.next = getelementptr inbounds i8, ptr addrspace(1) %p, i64 1
+ %c = icmp ult ptr addrspace(1) %p.next, %end
+ br i1 %c, label %loop, label %exit
+
+exit:
+ %res = phi ptr addrspace(1) [ %start, %entry ], [ %p.next, %loop ]
+ ret ptr addrspace(1) %res
+}
diff --git a/llvm/test/Transforms/LoopStrengthReduce/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll b/llvm/test/Transforms/LoopStrengthReduce/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
new file mode 100644
index 0000000000000..38d9ad1418373
--- /dev/null
+++ b/llvm/test/Transforms/LoopStrengthReduce/AArch64/expand-ptrtoaddr-reuse-ptrtoint.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes='loop-reduce' -S %s | FileCheck %s
+
+target triple = "arm64-apple-macosx"
+
+define i64 @expand_reuses_existing_ptrtoint(ptr %begin, ptr %end, ptr %cap) {
+; CHECK-LABEL: define i64 @expand_reuses_existing_ptrtoint(
+; CHECK-SAME: ptr [[BEGIN:%.*]], ptr [[END:%.*]], ptr [[CAP:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[BEGIN2:%.*]] = ptrtoint ptr [[BEGIN]] to i64
+; CHECK-NEXT: [[END1:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT: [[C0:%.*]] = icmp eq ptr [[BEGIN]], [[END]]
+; CHECK-NEXT: br i1 [[C0]], label %[[DONE:.*]], label %[[COUNT_PH:.*]]
+; CHECK: [[COUNT_PH]]:
+; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[END1]], -8
+; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[BEGIN2]]
+; CHECK-NEXT: [[TMP2:%.*]] = lshr i64 [[TMP1]], 3
+; CHECK-NEXT: [[TMP3:%.*]] = shl nuw i64 [[TMP2]], 3
+; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[TMP3]], 8
+; CHECK-NEXT: br label %[[COUNT:.*]]
+; CHECK: [[COUNT]]:
+; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[BEGIN]], %[[COUNT_PH]] ], [ [[PN:%.*]], %[[COUNT]] ]
+; CHECK-NEXT: [[PN]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8
+; CHECK-NEXT: [[D:%.*]] = icmp eq ptr [[PN]], [[END]]
+; CHECK-NEXT: br i1 [[D]], label %[[DONE_LOOPEXIT:.*]], label %[[COUNT]]
+; CHECK: [[DONE_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[DONE]]
+; CHECK: [[DONE]]:
+; CHECK-NEXT: [[USED:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[TMP4]], %[[DONE_LOOPEXIT]] ]
+; CHECK-NEXT: [[CAPI:%.*]] = ptrtoint ptr [[CAP]] to i64
+; CHECK-NEXT: [[ENDI:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT: [[SLACK:%.*]] = sub i64 [[CAPI]], [[ENDI]]
+; CHECK-NEXT: [[TOTAL:%.*]] = add i64 [[USED]], [[SLACK]]
+; CHECK-NEXT: ret i64 [[TOTAL]]
+;
+entry:
+ %c0 = icmp eq ptr %begin, %end
+ br i1 %c0, label %done, label %count.ph
+
+count.ph:
+ br label %count
+
+count:
+ %p = phi ptr [ %begin, %count.ph ], [ %pn, %count ]
+ %n = phi i64 [ 0, %count.ph ], [ %nn, %count ]
+ %pn = getelementptr inbounds nuw i8, ptr %p, i64 8
+ %nn = add i64 %n, 8
+ %d = icmp eq ptr %pn, %end
+ br i1 %d, label %done, label %count
+
+done:
+ %used = phi i64 [ 0, %entry ], [ %nn, %count ]
+ %capi = ptrtoint ptr %cap to i64
+ %endi = ptrtoint ptr %end to i64
+ %slack = sub i64 %capi, %endi
+ %total = add i64 %used, %slack
+ ret i64 %total
+}
diff --git a/llvm/test/Transforms/PhaseOrdering/X86/ptrtoaddr-ptrtoint.ll b/llvm/test/Transforms/PhaseOrdering/X86/ptrtoaddr-ptrtoint.ll
new file mode 100644
index 0000000000000..efcc1701c9bbe
--- /dev/null
+++ b/llvm/test/Transforms/PhaseOrdering/X86/ptrtoaddr-ptrtoint.ll
@@ -0,0 +1,379 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --version 6
+; RUN: opt -passes="default<O3>" -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+declare void @llvm.memmove.p0.p0.i64(ptr writeonly captures(none), ptr readonly captures(none), i64, i1 immarg)
+
+define void @redundant_int_iv(ptr %first) {
+; CHECK-LABEL: define void @redundant_int_iv(
+; CHECK-SAME: ptr [[FIRST:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[PTR_INT1:%.*]] = ptrtoint ptr [[FIRST]] to i64
+; CHECK-NEXT: [[OFF2:%.*]] = add i64 [[PTR_INT1]], 1
+; CHECK-NEXT: [[EC_OUTER3:%.*]] = icmp slt i64 [[OFF2]], 0
+; CHECK-NEXT: br i1 [[EC_OUTER3]], label %[[INNER_PH:.*]], label %[[EXIT:.*]]
+; CHECK: [[INNER_PH]]:
+; CHECK-NEXT: [[PTR_IV4:%.*]] = phi ptr [ [[LAST:%.*]], %[[INNER_PH]] ], [ [[FIRST]], %[[ENTRY]] ]
+; CHECK-NEXT: [[LAST]] = getelementptr i8, ptr [[PTR_IV4]], i64 7
+; CHECK-NEXT: [[CUR_NEXT:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 1
+; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[PTR_IV4]], align 1
+; CHECK-NEXT: store i8 [[TMP0]], ptr [[CUR_NEXT]], align 1
+; CHECK-NEXT: [[CUR_NEXT_1:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 2
+; CHECK-NEXT: [[TMP1:%.*]] = load i16, ptr [[PTR_IV4]], align 1
+; CHECK-NEXT: store i16 [[TMP1]], ptr [[CUR_NEXT_1]], align 1
+; CHECK-NEXT: [[CUR_NEXT_2:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 3
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[CUR_NEXT_2]], ptr noundef nonnull align 1 dereferenceable(3) [[PTR_IV4]], i64 3, i1 false)
+; CHECK-NEXT: [[CUR_NEXT_3:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 4
+; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[PTR_IV4]], align 1
+; CHECK-NEXT: store i32 [[TMP2]], ptr [[CUR_NEXT_3]], align 1
+; CHECK-NEXT: [[CUR_NEXT_4:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 5
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[CUR_NEXT_4]], ptr noundef nonnull align 1 dereferenceable(5) [[PTR_IV4]], i64 5, i1 false)
+; CHECK-NEXT: [[CUR_NEXT_5:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 6
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(6) [[CUR_NEXT_5]], ptr noundef nonnull align 1 dereferenceable(6) [[PTR_IV4]], i64 6, i1 false)
+; CHECK-NEXT: [[CUR_NEXT_6:%.*]] = getelementptr i8, ptr [[PTR_IV4]], i64 7
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(7) [[CUR_NEXT_6]], ptr noundef nonnull align 1 dereferenceable(7) [[PTR_IV4]], i64 7, i1 false)
+; CHECK-NEXT: [[PTR_INT:%.*]] = ptrtoint ptr [[LAST]] to i64
+; CHECK-NEXT: [[OFF:%.*]] = add i64 [[PTR_INT]], 1
+; CHECK-NEXT: [[EC_OUTER:%.*]] = icmp slt i64 [[OFF]], 0
+; CHECK-NEXT: br i1 [[EC_OUTER]], label %[[INNER_PH]], label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %outer
+
+outer:
+ %ptr.iv = phi ptr [ %first, %entry ], [ %ptr.next, %inner.exit ]
+ %ptr.int = ptrtoint ptr %ptr.iv to i64
+ %off = add i64 %ptr.int, 1
+ %ec.outer = icmp slt i64 %off, 0
+ br i1 %ec.outer, label %inner.ph, label %exit
+
+inner.ph:
+ %last = getelementptr i8, ptr %ptr.iv, i64 7
+ br label %inner
+
+inner:
+ %cur = phi ptr [ %ptr.iv, %inner.ph ], [ %cur.next, %inner ]
+ %cur.next = getelementptr i8, ptr %cur, i64 1
+ %cur.int = ptrtoint ptr %cur.next to i64
+ %len = sub i64 %cur.int, %ptr.int
+ call void @llvm.memmove.p0.p0.i64(ptr %cur.next, ptr %ptr.iv, i64 %len, i1 false)
+ %inner.done = icmp eq ptr %cur.next, %last
+ br i1 %inner.done, label %inner.exit, label %inner
+
+inner.exit:
+ %ptr.next = getelementptr i8, ptr %ptr.iv, i64 7
+ br label %outer
+
+exit:
+ ret void
+}
+
+define ptr @cancel_out_of_range(ptr %p) {
+; CHECK-LABEL: define noalias noundef ptr @cancel_out_of_range(
+; CHECK-SAME: ptr [[P:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P1:%.*]] = ptrtoint ptr [[P]] to i64
+; CHECK-NEXT: store ptr [[P]], ptr [[P]], align 8
+; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[P1]], 255
+; CHECK-NEXT: [[IS_ZERO:%.*]] = icmp eq i64 [[TMP0]], 0
+; CHECK-NEXT: [[SPEC_SELECT_IDX:%.*]] = select i1 [[IS_ZERO]], i64 0, i64 [[P1]]
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = getelementptr i8, ptr null, i64 [[SPEC_SELECT_IDX]]
+; CHECK-NEXT: ret ptr [[SPEC_SELECT]]
+;
+entry:
+ store ptr %p, ptr %p, align 8
+ %first = load i8, ptr %p, align 1
+ %is.zero = icmp eq i8 %first, 0
+ br i1 %is.zero, label %exit, label %loop
+
+exit:
+ %res = phi ptr [ null, %entry ], [ %cur, %loop ]
+ ret ptr %res
+
+loop:
+ %cur = phi ptr [ null, %entry ], [ %prev, %loop.dec ]
+ %found = icmp eq ptr %cur, %p
+ br i1 %found, label %exit, label %loop.dec
+
+loop.dec:
+ %prev = getelementptr i8, ptr %cur, i64 -1
+ br label %loop
+}
+
+ at end = external global i8
+
+define i64 @cse_two_guards(ptr %base, i64 %n, ptr %cmp) {
+; CHECK-LABEL: define i64 @cse_two_guards(
+; CHECK-SAME: ptr [[BASE:%.*]], i64 [[N:%.*]], ptr nofree readonly captures(none) [[CMP:%.*]]) local_unnamed_addr #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[N_FR:%.*]] = freeze i64 [[N]]
+; CHECK-NEXT: store ptr [[BASE]], ptr [[BASE]], align 8
+; CHECK-NEXT: [[NE_I_NOT6:%.*]] = icmp eq ptr [[BASE]], @end
+; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[BASE]] to i64
+; CHECK-NEXT: br i1 [[NE_I_NOT6]], label %[[RET:.*]], label %[[LOOP1_INC_PREHEADER:.*]]
+; CHECK: [[LOOP1_INC_PREHEADER]]:
+; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[BASE]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = sub i64 add (i64 ptrtoint (ptr @end to i64), i64 -48), [[TMP1]]
+; CHECK-NEXT: [[TMP3:%.*]] = udiv i64 [[TMP2]], 48
+; CHECK-NEXT: [[TMP4:%.*]] = add nuw nsw i64 [[TMP3]], 1
+; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 144
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[LOOP1_INC_PREHEADER41:.*]], label %[[VECTOR_PH:.*]]
+; CHECK: [[VECTOR_PH]]:
+; CHECK-NEXT: [[N_VEC:%.*]] = and i64 [[TMP4]], 1152921504606846972
+; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[N_VEC]], 48
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP5]]
+; CHECK-NEXT: [[TMP7:%.*]] = icmp ult i64 [[N_FR]], 2
+; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
+; CHECK: [[VECTOR_BODY]]:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
+; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[TMP8]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK]]:
+; CHECK-NEXT: [[RDX_SELECT:%.*]] = zext i1 [[TMP7]] to i64
+; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP4]], [[N_VEC]]
+; CHECK-NEXT: br i1 [[CMP_N]], label %[[LOOP2_BODY_LR_PH:.*]], label %[[LOOP1_INC_PREHEADER41]]
+; CHECK: [[LOOP1_INC_PREHEADER41]]:
+; CHECK-NEXT: [[R8_PH:%.*]] = phi i64 [ 1, %[[LOOP1_INC_PREHEADER]] ], [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ]
+; CHECK-NEXT: [[IT1_07_PH:%.*]] = phi ptr [ [[BASE]], %[[LOOP1_INC_PREHEADER]] ], [ [[TMP6]], %[[MIDDLE_BLOCK]] ]
+; CHECK-NEXT: br label %[[LOOP1_INC:.*]]
+; CHECK: [[LOOP2_BODY_LR_PH]]:
+; CHECK-NEXT: [[SEL_LCSSA:%.*]] = phi i64 [ [[RDX_SELECT]], %[[MIDDLE_BLOCK]] ], [ [[SEL:%.*]], %[[LOOP1_INC]] ]
+; CHECK-NEXT: [[TMP9:%.*]] = uitofp nneg i64 [[SEL_LCSSA]] to double
+; CHECK-NEXT: [[MIN_ITERS_CHECK18:%.*]] = icmp ult i64 [[TMP2]], 144
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK18]], label %[[LOOP2_BODY_PREHEADER:.*]], label %[[VECTOR_MEMCHECK:.*]]
+; CHECK: [[VECTOR_MEMCHECK]]:
+; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[BASE]], i64 8
+; CHECK-NEXT: [[SCEVGEP16:%.*]] = getelementptr i8, ptr [[CMP]], i64 8
+; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[BASE]], [[SCEVGEP16]]
+; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[CMP]], [[SCEVGEP]]
+; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
+; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %[[LOOP2_BODY_PREHEADER]], label %[[VECTOR_PH19:.*]]
+; CHECK: [[VECTOR_PH19]]:
+; CHECK-NEXT: [[N_VEC21:%.*]] = and i64 [[TMP4]], 1152921504606846974
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT22:%.*]] = insertelement <2 x double> poison, double [[TMP9]], i64 0
+; CHECK-NEXT: [[TMP10:%.*]] = mul i64 [[N_VEC21]], 48
+; CHECK-NEXT: [[TMP11:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP10]]
+; CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr [[CMP]], align 8, !alias.scope [[META3:![0-9]+]]
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT24:%.*]] = insertelement <2 x i64> poison, i64 [[TMP12]], i64 0
+; CHECK-NEXT: [[TMP13:%.*]] = uitofp <2 x i64> [[BROADCAST_SPLATINSERT24]] to <2 x double>
+; CHECK-NEXT: [[TMP14:%.*]] = fmul nnan <2 x double> [[BROADCAST_SPLATINSERT22]], [[TMP13]]
+; CHECK-NEXT: [[TMP15:%.*]] = fcmp ugt <2 x double> [[TMP14]], zeroinitializer
+; CHECK-NEXT: [[TMP16:%.*]] = shufflevector <2 x i1> [[TMP15]], <2 x i1> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP17:%.*]] = freeze <2 x i1> [[TMP16]]
+; CHECK-NEXT: [[TMP18:%.*]] = bitcast <2 x i1> [[TMP17]] to i2
+; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i2 [[TMP18]], 0
+; CHECK-NEXT: [[BROADCAST_SPLATINSERT26:%.*]] = insertelement <2 x i64> poison, i64 [[TMP0]], i64 0
+; CHECK-NEXT: [[BROADCAST_SPLAT27:%.*]] = shufflevector <2 x i64> [[BROADCAST_SPLATINSERT26]], <2 x i64> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP19:%.*]] = bitcast <2 x i1> [[TMP17]] to i2
+; CHECK-NEXT: [[DOTNOT39:%.*]] = icmp eq i2 [[TMP19]], 0
+; CHECK-NEXT: br label %[[VECTOR_BODY28:.*]]
+; CHECK: [[VECTOR_BODY28]]:
+; CHECK-NEXT: [[INDEX29:%.*]] = phi i64 [ 0, %[[VECTOR_PH19]] ], [ [[INDEX_NEXT33:%.*]], %[[TMP22:.*]] ]
+; CHECK-NEXT: [[VEC_PHI30:%.*]] = phi <2 x i64> [ [[BROADCAST_SPLAT27]], %[[VECTOR_PH19]] ], [ [[TMP24:%.*]], %[[TMP22]] ]
+; CHECK-NEXT: [[TMP20:%.*]] = phi <2 x i1> [ zeroinitializer, %[[VECTOR_PH19]] ], [ [[TMP23:%.*]], %[[TMP22]] ]
+; CHECK-NEXT: br i1 [[DOTNOT39]], label %[[TMP22]], label %[[BB21:.*]]
+; CHECK: [[BB21]]:
+; CHECK-NEXT: store i64 0, ptr [[BASE]], align 8, !alias.scope [[META6:![0-9]+]], !noalias [[META3]]
+; CHECK-NEXT: br label %[[TMP22]]
+; CHECK: [[TMP22]]:
+; CHECK-NEXT: [[TMP23]] = select i1 [[DOTNOT]], <2 x i1> [[TMP20]], <2 x i1> [[TMP17]]
+; CHECK-NEXT: [[TMP24]] = select i1 [[DOTNOT]], <2 x i64> [[VEC_PHI30]], <2 x i64> zeroinitializer
+; CHECK-NEXT: [[INDEX_NEXT33]] = add nuw i64 [[INDEX29]], 2
+; CHECK-NEXT: [[TMP25:%.*]] = icmp eq i64 [[INDEX_NEXT33]], [[N_VEC21]]
+; CHECK-NEXT: br i1 [[TMP25]], label %[[MIDDLE_BLOCK34:.*]], label %[[VECTOR_BODY28]], !llvm.loop [[LOOP8:![0-9]+]]
+; CHECK: [[MIDDLE_BLOCK34]]:
+; CHECK-NEXT: [[TMP26:%.*]] = tail call i64 @llvm.experimental.vector.extract.last.active.v2i64(<2 x i64> [[TMP24]], <2 x i1> [[TMP23]], i64 [[TMP0]])
+; CHECK-NEXT: [[CMP_N35:%.*]] = icmp eq i64 [[TMP4]], [[N_VEC21]]
+; CHECK-NEXT: br i1 [[CMP_N35]], label %[[RET]], label %[[LOOP2_BODY_PREHEADER]]
+; CHECK: [[LOOP2_BODY_PREHEADER]]:
+; CHECK-NEXT: [[RES12_PH:%.*]] = phi i64 [ [[TMP0]], %[[VECTOR_MEMCHECK]] ], [ [[TMP0]], %[[LOOP2_BODY_LR_PH]] ], [ [[TMP26]], %[[MIDDLE_BLOCK34]] ]
+; CHECK-NEXT: [[IT2_010_PH:%.*]] = phi ptr [ [[BASE]], %[[VECTOR_MEMCHECK]] ], [ [[BASE]], %[[LOOP2_BODY_LR_PH]] ], [ [[TMP11]], %[[MIDDLE_BLOCK34]] ]
+; CHECK-NEXT: br label %[[LOOP2_BODY:.*]]
+; CHECK: [[LOOP1_INC]]:
+; CHECK-NEXT: [[R8:%.*]] = phi i64 [ [[SEL]], %[[LOOP1_INC]] ], [ [[R8_PH]], %[[LOOP1_INC_PREHEADER41]] ]
+; CHECK-NEXT: [[IT1_07:%.*]] = phi ptr [ [[NEXT_I:%.*]], %[[LOOP1_INC]] ], [ [[IT1_07_PH]], %[[LOOP1_INC_PREHEADER41]] ]
+; CHECK-NEXT: [[GT:%.*]] = icmp ugt i64 [[N_FR]], [[R8]]
+; CHECK-NEXT: [[SEL]] = select i1 [[GT]], i64 0, i64 [[R8]]
+; CHECK-NEXT: [[NEXT_I]] = getelementptr nusw nuw i8, ptr [[IT1_07]], i64 48
+; CHECK-NEXT: [[NE_I_NOT:%.*]] = icmp eq ptr [[NEXT_I]], @end
+; CHECK-NEXT: br i1 [[NE_I_NOT]], label %[[LOOP2_BODY_LR_PH]], label %[[LOOP1_INC]], !llvm.loop [[LOOP9:![0-9]+]]
+; CHECK: [[RET]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[TMP0]], %[[ENTRY]] ], [ [[TMP26]], %[[MIDDLE_BLOCK34]] ], [ [[RES11:%.*]], %[[LOOP2_INC:.*]] ]
+; CHECK-NEXT: ret i64 [[RES]]
+; CHECK: [[LOOP2_BODY]]:
+; CHECK-NEXT: [[RES12:%.*]] = phi i64 [ [[RES11]], %[[LOOP2_INC]] ], [ [[RES12_PH]], %[[LOOP2_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[IT2_010:%.*]] = phi ptr [ [[NEXT_I5:%.*]], %[[LOOP2_INC]] ], [ [[IT2_010_PH]], %[[LOOP2_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[CMP_VAL_I:%.*]] = load i64, ptr [[CMP]], align 8
+; CHECK-NEXT: [[CMP_F_I:%.*]] = uitofp i64 [[CMP_VAL_I]] to double
+; CHECK-NEXT: [[PROD_I:%.*]] = fmul nnan double [[TMP9]], [[CMP_F_I]]
+; CHECK-NEXT: [[OLE_I:%.*]] = fcmp ugt double [[PROD_I]], 0.000000e+00
+; CHECK-NEXT: br i1 [[OLE_I]], label %[[CLEAR:.*]], label %[[LOOP2_INC]]
+; CHECK: [[CLEAR]]:
+; CHECK-NEXT: store i64 0, ptr [[BASE]], align 8
+; CHECK-NEXT: br label %[[LOOP2_INC]]
+; CHECK: [[LOOP2_INC]]:
+; CHECK-NEXT: [[RES11]] = phi i64 [ 0, %[[CLEAR]] ], [ [[RES12]], %[[LOOP2_BODY]] ]
+; CHECK-NEXT: [[NEXT_I5]] = getelementptr nusw nuw i8, ptr [[IT2_010]], i64 48
+; CHECK-NEXT: [[NE_I3_NOT:%.*]] = icmp eq ptr [[NEXT_I5]], @end
+; CHECK-NEXT: br i1 [[NE_I3_NOT]], label %[[RET]], label %[[LOOP2_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
+;
+entry:
+ %it1 = alloca ptr, align 8
+ %lam = alloca i64, align 8
+ %it2 = alloca ptr, align 8
+ store ptr %base, ptr %it1, align 8
+ store ptr %base, ptr %base, align 8
+ br label %loop1
+
+loop1:
+ %r = phi i64 [ 1, %entry ], [ %sel, %loop1.inc ]
+ %ne1 = call i1 @iter_ne(ptr %it1)
+ br i1 %ne1, label %loop1.inc, label %between
+
+loop1.inc:
+ %gt = icmp ugt i64 %n, %r
+ %sel = select i1 %gt, i64 0, i64 %r
+ %adv1 = call ptr @iter_inc(ptr %it1)
+ br label %loop1
+
+between:
+ store i64 %r, ptr %lam, align 8
+ store ptr %base, ptr %it2, align 8
+ br label %loop2
+
+loop2:
+ %ne2 = call i1 @iter_ne(ptr %it2)
+ br i1 %ne2, label %loop2.body, label %ret
+
+ret:
+ %res = load i64, ptr %base, align 8
+ ret i64 %res
+
+loop2.body:
+ %pred = call i1 @lambda(ptr %lam, ptr %cmp)
+ br i1 %pred, label %loop2.inc, label %clear
+
+clear:
+ store i64 0, ptr %base, align 8
+ br label %loop2.inc
+
+loop2.inc:
+ %adv2 = call ptr @iter_inc(ptr %it2)
+ br label %loop2
+}
+
+define i1 @iter_ne(ptr %it) {
+; CHECK-LABEL: define i1 @iter_ne(
+; CHECK-SAME: ptr nofree readonly captures(none) [[IT:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT: [[CUR:%.*]] = load ptr, ptr [[IT]], align 8
+; CHECK-NEXT: [[NE:%.*]] = icmp ne ptr [[CUR]], @end
+; CHECK-NEXT: ret i1 [[NE]]
+;
+ %cur = load ptr, ptr %it, align 8
+ %ne = icmp ne ptr %cur, @end
+ ret i1 %ne
+}
+
+define ptr @iter_inc(ptr %it) {
+; CHECK-LABEL: define noalias noundef ptr @iter_inc(
+; CHECK-SAME: ptr nofree captures(none) [[IT:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT: [[CUR:%.*]] = load ptr, ptr [[IT]], align 8
+; CHECK-NEXT: [[NEXT:%.*]] = getelementptr nusw nuw i8, ptr [[CUR]], i64 48
+; CHECK-NEXT: store ptr [[NEXT]], ptr [[IT]], align 8
+; CHECK-NEXT: ret ptr null
+;
+ %cur = load ptr, ptr %it, align 8
+ %next = getelementptr nusw i8, ptr %cur, i64 48
+ store ptr %next, ptr %it, align 8
+ ret ptr null
+}
+
+define i1 @lambda(ptr %lam, ptr %cmp) {
+; CHECK-LABEL: define i1 @lambda(
+; CHECK-SAME: ptr nofree readonly captures(none) [[LAM:%.*]], ptr nofree readonly captures(none) [[CMP:%.*]]) local_unnamed_addr #[[ATTR2]] {
+; CHECK-NEXT: [[CMP_VAL:%.*]] = load i64, ptr [[CMP]], align 8
+; CHECK-NEXT: [[CMP_F:%.*]] = uitofp i64 [[CMP_VAL]] to double
+; CHECK-NEXT: [[LAM_VAL:%.*]] = load i64, ptr [[LAM]], align 8
+; CHECK-NEXT: [[LAM_F:%.*]] = uitofp i64 [[LAM_VAL]] to double
+; CHECK-NEXT: [[PROD:%.*]] = fmul nnan double [[CMP_F]], [[LAM_F]]
+; CHECK-NEXT: [[OLE:%.*]] = fcmp ole double [[PROD]], 0.000000e+00
+; CHECK-NEXT: ret i1 [[OLE]]
+;
+ %cmp.val = load i64, ptr %cmp, align 8
+ %cmp.f = uitofp i64 %cmp.val to double
+ %lam.val = load i64, ptr %lam, align 8
+ %lam.f = uitofp i64 %lam.val to double
+ %prod = fmul double %cmp.f, %lam.f
+ %ole = fcmp ole double %prod, 0.000000e+00
+ ret i1 %ole
+}
+
+define ptr @gep_base_cancel(ptr %p, ptr %end, ptr noalias %a) {
+; CHECK-LABEL: define noundef ptr @gep_base_cancel(
+; CHECK-SAME: ptr nofree readonly captures(address) [[P:%.*]], ptr nofree readnone captures(address) [[END:%.*]], ptr noalias nofree captures(address, ret: address, provenance) [[A:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[IN_BOUNDS6:%.*]] = icmp ult ptr [[P]], [[END]]
+; CHECK-NEXT: br i1 [[IN_BOUNDS6]], label %[[BODY_PREHEADER:.*]], label %[[COMMON_RET:.*]]
+; CHECK: [[BODY_PREHEADER]]:
+; CHECK-NEXT: [[END15:%.*]] = ptrtoint ptr [[END]] to i64
+; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr inttoptr (i64 -1 to ptr), i64 [[END15]]
+; CHECK-NEXT: [[CHAR_PEEL:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT: switch i8 [[CHAR_PEEL]], label %[[TRAP:.*]] [
+; CHECK-NEXT: i8 33, label %[[ADVANCE_PEEL:.*]]
+; CHECK-NEXT: i8 36, label %[[ADVANCE_PEEL]]
+; CHECK-NEXT: ]
+; CHECK: [[ADVANCE_PEEL]]:
+; CHECK-NEXT: [[EXITCOND_PEEL_NOT:%.*]] = icmp eq ptr [[P]], [[SCEVGEP]]
+; CHECK-NEXT: br i1 [[EXITCOND_PEEL_NOT]], label %[[COMMON_RET]], label %[[BODY:.*]]
+; CHECK: [[COMMON_RET]]:
+; CHECK-NEXT: [[RET_KNOWN_TR3:%.*]] = phi ptr [ [[A_TR9_LCSSA:%.*]], %[[TRAP]] ], [ null, %[[ENTRY]] ], [ null, %[[ADVANCE_PEEL]] ], [ null, %[[ADVANCE:.*]] ]
+; CHECK-NEXT: ret ptr [[RET_KNOWN_TR3]]
+; CHECK: [[BODY]]:
+; CHECK-NEXT: [[P_TR7_PN:%.*]] = phi ptr [ [[P_TR7:%.*]], %[[ADVANCE]] ], [ [[P]], %[[ADVANCE_PEEL]] ]
+; CHECK-NEXT: [[P_TR7]] = getelementptr i8, ptr [[P_TR7_PN]], i64 1
+; CHECK-NEXT: [[CHAR:%.*]] = load i8, ptr [[P_TR7]], align 1
+; CHECK-NEXT: switch i8 [[CHAR]], label %[[TRAP]] [
+; CHECK-NEXT: i8 33, label %[[ADVANCE]]
+; CHECK-NEXT: i8 36, label %[[ADVANCE]]
+; CHECK-NEXT: ]
+; CHECK: [[ADVANCE]]:
+; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq ptr [[P_TR7]], [[SCEVGEP]]
+; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[COMMON_RET]], label %[[BODY]], !llvm.loop [[LOOP11:![0-9]+]]
+; CHECK: [[TRAP]]:
+; CHECK-NEXT: [[A_TR9_LCSSA]] = phi ptr [ [[A]], %[[BODY_PREHEADER]] ], [ null, %[[BODY]] ]
+; CHECK-NEXT: store volatile i32 0, ptr [[A_TR9_LCSSA]], align 4
+; CHECK-NEXT: br label %[[COMMON_RET]]
+;
+entry:
+ %in.bounds = icmp ult ptr %p, %end
+ br i1 %in.bounds, label %body, label %common.ret
+
+common.ret:
+ %ret = phi ptr [ %a, %trap ], [ null, %recurse ], [ null, %advance ], [ null, %entry ]
+ ret ptr %ret
+
+body:
+ %char = load i8, ptr %p, align 1
+ switch i8 %char, label %trap [
+ i8 33, label %advance
+ i8 36, label %advance
+ ]
+
+advance:
+ %p.next = getelementptr i8, ptr %p, i64 1
+ %next.in.bounds = icmp ult ptr %p.next, %end
+ br i1 %next.in.bounds, label %recurse, label %common.ret
+
+recurse:
+ %rec = call ptr @gep_base_cancel(ptr %p.next, ptr %end)
+ br label %common.ret
+
+trap:
+ store volatile i32 0, ptr %a, align 4
+ br label %common.ret
+}
More information about the llvm-commits
mailing list