From 5fdcb35aaa4e01f001780f2dcda38e16395d7d18 Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Fri, 27 Jun 2025 12:10:57 +0100 Subject: [PATCH] [InferAlignment] Add tests with GEP recurrences. Add some test coverage for GEP recurrences in ValueTracking, https://github.com/llvm/llvm-project/pull/123518. --- .../InferAlignment/gep-recurrence.ll | 574 ++++++++++++++++++ 1 file changed, 574 insertions(+) create mode 100644 llvm/test/Transforms/InferAlignment/gep-recurrence.ll diff --git a/llvm/test/Transforms/InferAlignment/gep-recurrence.ll b/llvm/test/Transforms/InferAlignment/gep-recurrence.ll new file mode 100644 index 000000000000..50b968d206b8 --- /dev/null +++ b/llvm/test/Transforms/InferAlignment/gep-recurrence.ll @@ -0,0 +1,574 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -passes=infer-alignment -S %s | FileCheck %s + +target datalayout = "p1:64:64:64:32" + +declare i1 @cond() + +define void @recur_i8_128(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_128( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 128 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 128 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_128_no_nusw(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_128_no_nusw( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr i8, ptr [[IV]], i64 128 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr i8, ptr %iv, i64 128 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_64(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_64( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 64 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 64 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_63(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_63( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 63 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 63 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_32(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_32( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 32 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 32 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_16(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_16( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 16 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 16 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_8(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_8( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 8 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 8 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_4(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_4( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 4 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 4 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_2(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_2( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 2 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 2 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_1(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_1( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 1 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 1 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_unknown_step(ptr align 128 %dst, i64 %off) { +; CHECK-LABEL: define void @recur_i8_unknown_step( +; CHECK-SAME: ptr align 128 [[DST:%.*]], i64 [[OFF:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 [[OFF]] +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 %off + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_step_known_multiple(ptr align 128 %dst, i64 %off) { +; CHECK-LABEL: define void @recur_i8_step_known_multiple( +; CHECK-SAME: ptr align 128 [[DST:%.*]], i64 [[OFF:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: [[UREM:%.*]] = urem i64 [[OFF]], 128 +; CHECK-NEXT: [[C_UREM:%.*]] = icmp eq i64 [[UREM]], 0 +; CHECK-NEXT: [[C_POS:%.*]] = icmp sge i64 [[OFF]], 0 +; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_UREM]], [[C_POS]] +; CHECK-NEXT: br i1 [[AND]], label %[[LOOP:.*]], label %[[EXIT:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 [[OFF]] +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + %urem = urem i64 %off, 128 + %c.urem = icmp eq i64 %urem, 0 + %c.pos = icmp sge i64 %off, 0 + %and = and i1 %c.urem, %c.pos + br i1 %and, label %loop, label %exit + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 %off + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_i16_128(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_i16_128( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i16 128 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i16 128 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_i8_132(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_i8_132( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i8 -124 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i8 132 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i32_4(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i32_4( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i32, ptr [[IV]], i64 4 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i32, ptr %iv, i64 4 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i32_3(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i32_3( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i32, ptr [[IV]], i64 4 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i32, ptr %iv, i64 4 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_neg_128(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_neg_128( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 -128 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 -128 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_neg64(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_neg64( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 -64 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 -64 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_neg_63(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_neg_63( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 -63 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 -63 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +} + +define void @recur_i8_neg_32(ptr align 128 %dst) { +; CHECK-LABEL: define void @recur_i8_neg_32( +; CHECK-SAME: ptr align 128 [[DST:%.*]]) { +; CHECK-NEXT: [[ENTRY:.*]]: +; CHECK-NEXT: br label %[[LOOP:.*]] +; CHECK: [[LOOP]]: +; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[DST]], %[[ENTRY]] ], [ [[IV_NEXT:%.*]], %[[LOOP]] ] +; CHECK-NEXT: store i64 0, ptr [[IV]], align 1 +; CHECK-NEXT: [[IV_NEXT]] = getelementptr nusw i8, ptr [[IV]], i64 -32 +; CHECK-NEXT: [[C:%.*]] = call i1 @cond() +; CHECK-NEXT: br i1 [[C]], label %[[LOOP]], label %[[EXIT:.*]] +; CHECK: [[EXIT]]: +; CHECK-NEXT: ret void +; +entry: + br label %loop + +loop: + %iv = phi ptr [ %dst, %entry ], [ %iv.next, %loop ] + store i64 0, ptr %iv, align 1 + %iv.next = getelementptr nusw i8, ptr %iv, i64 -32 + %c = call i1 @cond() + br i1 %c, label %loop, label %exit + +exit: + ret void +}