| ; 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:%.*]] = ptrtoaddr 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:%.*]] = ptrtoaddr ptr [[START]] to i64 |
| ; CHECK-NEXT: [[BOUND2:%.*]] = ptrtoaddr 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 |
| } |