|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| 2 | +; RUN: opt < %s -passes=loop-vectorize -mtriple=aarch64-unknown-linux-gnu -S | FileCheck %s --check-prefix=AARCH64 |
| 3 | +; RUN: opt < %s -passes=loop-vectorize -mtriple=x86_64-unknown-linux-gnu -S | FileCheck %s --check-prefix=X86_64 |
| 4 | + |
| 5 | +; Testcase extraído de ElemAttribute.cpp |
| 6 | +; Foca no loop while.body que copia elementos i16 |
| 7 | + |
| 8 | +target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" |
| 9 | + |
| 10 | +; This test introduces a case where a memory induction variable |
| 11 | +; stops vectorization. This test will be updated when hoisting loads |
| 12 | +; for this memory induction variable and vectorization is possible. |
| 13 | +define void @test_copy_loop(ptr %theFirst, ptr %theLast, ptr %dest_base, ptr %m_size_ptr) { |
| 14 | +; AARCH64-LABEL: define void @test_copy_loop( |
| 15 | +; AARCH64-SAME: ptr [[THEFIRST:%.*]], ptr [[THELAST:%.*]], ptr [[DEST_BASE:%.*]], ptr [[M_SIZE_PTR:%.*]]) { |
| 16 | +; AARCH64-NEXT: [[ENTRY:.*:]] |
| 17 | +; AARCH64-NEXT: [[TMP0:%.*]] = load i64, ptr [[M_SIZE_PTR]], align 8 |
| 18 | +; AARCH64-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds nuw i16, ptr [[DEST_BASE]], i64 [[TMP0]] |
| 19 | +; AARCH64-NEXT: [[CMP_NOT:%.*]] = icmp eq ptr [[THEFIRST]], [[THELAST]] |
| 20 | +; AARCH64-NEXT: br i1 [[CMP_NOT]], label %[[CLEANUP:.*]], label %[[WHILE_BODY_PREHEADER:.*]] |
| 21 | +; AARCH64: [[WHILE_BODY_PREHEADER]]: |
| 22 | +; AARCH64-NEXT: br label %[[WHILE_BODY:.*]] |
| 23 | +; AARCH64: [[WHILE_BODY]]: |
| 24 | +; AARCH64-NEXT: [[THEFIRST_ADDR_0112:%.*]] = phi ptr [ [[INCDEC_PTR9:%.*]], %[[WHILE_BODY]] ], [ [[THEFIRST]], %[[WHILE_BODY_PREHEADER]] ] |
| 25 | +; AARCH64-NEXT: [[THEPOINTER_0111:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], %[[WHILE_BODY]] ], [ [[ADD_PTR_I]], %[[WHILE_BODY_PREHEADER]] ] |
| 26 | +; AARCH64-NEXT: [[TMP1:%.*]] = load i16, ptr [[THEFIRST_ADDR_0112]], align 2 |
| 27 | +; AARCH64-NEXT: store i16 [[TMP1]], ptr [[THEPOINTER_0111]], align 2 |
| 28 | +; AARCH64-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[THEPOINTER_0111]], i64 2 |
| 29 | +; AARCH64-NEXT: [[TMP2:%.*]] = load i64, ptr [[M_SIZE_PTR]], align 8 |
| 30 | +; AARCH64-NEXT: [[INC:%.*]] = add i64 [[TMP2]], 1 |
| 31 | +; AARCH64-NEXT: store i64 [[INC]], ptr [[M_SIZE_PTR]], align 8 |
| 32 | +; AARCH64-NEXT: [[INCDEC_PTR9]] = getelementptr inbounds nuw i8, ptr [[THEFIRST_ADDR_0112]], i64 2 |
| 33 | +; AARCH64-NEXT: [[CMP7_NOT:%.*]] = icmp eq ptr [[INCDEC_PTR9]], [[THELAST]] |
| 34 | +; AARCH64-NEXT: br i1 [[CMP7_NOT]], label %[[CLEANUP_LOOPEXIT:.*]], label %[[WHILE_BODY]] |
| 35 | +; AARCH64: [[CLEANUP_LOOPEXIT]]: |
| 36 | +; AARCH64-NEXT: br label %[[CLEANUP]] |
| 37 | +; AARCH64: [[CLEANUP]]: |
| 38 | +; AARCH64-NEXT: ret void |
| 39 | +; |
| 40 | +; X86_64-LABEL: define void @test_copy_loop( |
| 41 | +; X86_64-SAME: ptr [[THEFIRST:%.*]], ptr [[THELAST:%.*]], ptr [[DEST_BASE:%.*]], ptr [[M_SIZE_PTR:%.*]]) { |
| 42 | +; X86_64-NEXT: [[ENTRY:.*:]] |
| 43 | +; X86_64-NEXT: [[TMP0:%.*]] = load i64, ptr [[M_SIZE_PTR]], align 8 |
| 44 | +; X86_64-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds nuw i16, ptr [[DEST_BASE]], i64 [[TMP0]] |
| 45 | +; X86_64-NEXT: [[CMP_NOT:%.*]] = icmp eq ptr [[THEFIRST]], [[THELAST]] |
| 46 | +; X86_64-NEXT: br i1 [[CMP_NOT]], label %[[CLEANUP:.*]], label %[[WHILE_BODY_PREHEADER:.*]] |
| 47 | +; X86_64: [[WHILE_BODY_PREHEADER]]: |
| 48 | +; X86_64-NEXT: br label %[[WHILE_BODY:.*]] |
| 49 | +; X86_64: [[WHILE_BODY]]: |
| 50 | +; X86_64-NEXT: [[THEFIRST_ADDR_0112:%.*]] = phi ptr [ [[INCDEC_PTR9:%.*]], %[[WHILE_BODY]] ], [ [[THEFIRST]], %[[WHILE_BODY_PREHEADER]] ] |
| 51 | +; X86_64-NEXT: [[THEPOINTER_0111:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], %[[WHILE_BODY]] ], [ [[ADD_PTR_I]], %[[WHILE_BODY_PREHEADER]] ] |
| 52 | +; X86_64-NEXT: [[TMP1:%.*]] = load i16, ptr [[THEFIRST_ADDR_0112]], align 2 |
| 53 | +; X86_64-NEXT: store i16 [[TMP1]], ptr [[THEPOINTER_0111]], align 2 |
| 54 | +; X86_64-NEXT: [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[THEPOINTER_0111]], i64 2 |
| 55 | +; X86_64-NEXT: [[TMP2:%.*]] = load i64, ptr [[M_SIZE_PTR]], align 8 |
| 56 | +; X86_64-NEXT: [[INC:%.*]] = add i64 [[TMP2]], 1 |
| 57 | +; X86_64-NEXT: store i64 [[INC]], ptr [[M_SIZE_PTR]], align 8 |
| 58 | +; X86_64-NEXT: [[INCDEC_PTR9]] = getelementptr inbounds nuw i8, ptr [[THEFIRST_ADDR_0112]], i64 2 |
| 59 | +; X86_64-NEXT: [[CMP7_NOT:%.*]] = icmp eq ptr [[INCDEC_PTR9]], [[THELAST]] |
| 60 | +; X86_64-NEXT: br i1 [[CMP7_NOT]], label %[[CLEANUP_LOOPEXIT:.*]], label %[[WHILE_BODY]] |
| 61 | +; X86_64: [[CLEANUP_LOOPEXIT]]: |
| 62 | +; X86_64-NEXT: br label %[[CLEANUP]] |
| 63 | +; X86_64: [[CLEANUP]]: |
| 64 | +; X86_64-NEXT: ret void |
| 65 | +; |
| 66 | + |
| 67 | +entry: |
| 68 | + %0 = load i64, ptr %m_size_ptr, align 8 |
| 69 | + %add.ptr.i = getelementptr inbounds nuw i16, ptr %dest_base, i64 %0 |
| 70 | + %cmp.not = icmp eq ptr %theFirst, %theLast |
| 71 | + br i1 %cmp.not, label %cleanup, label %while.body.preheader |
| 72 | + |
| 73 | +while.body.preheader: |
| 74 | + br label %while.body |
| 75 | + |
| 76 | +while.body: |
| 77 | + %theFirst.addr.0112 = phi ptr [ %incdec.ptr9, %while.body ], [ %theFirst, %while.body.preheader ] |
| 78 | + %thePointer.0111 = phi ptr [ %incdec.ptr, %while.body ], [ %add.ptr.i, %while.body.preheader ] |
| 79 | + %1 = load i16, ptr %theFirst.addr.0112, align 2 |
| 80 | + store i16 %1, ptr %thePointer.0111, align 2 |
| 81 | + %incdec.ptr = getelementptr inbounds nuw i8, ptr %thePointer.0111, i64 2 |
| 82 | + %2 = load i64, ptr %m_size_ptr, align 8 |
| 83 | + %inc = add i64 %2, 1 |
| 84 | + store i64 %inc, ptr %m_size_ptr, align 8 |
| 85 | + %incdec.ptr9 = getelementptr inbounds nuw i8, ptr %theFirst.addr.0112, i64 2 |
| 86 | + %cmp7.not = icmp eq ptr %incdec.ptr9, %theLast |
| 87 | + br i1 %cmp7.not, label %cleanup.loopexit, label %while.body |
| 88 | + |
| 89 | +cleanup.loopexit: |
| 90 | + br label %cleanup |
| 91 | + |
| 92 | +cleanup: |
| 93 | + ret void |
| 94 | +} |
0 commit comments