1; RUN: opt -passes=loop-vectorize -force-vector-width=2 -S %s | FileCheck %s 2 3; Tests with alias sets that contain points with uncomputable bounds because 4; they include %offset.1, which is loaded in each loop iteration. 5 6; Alias set with uncomputable bounds contains a single load. We do not need 7; runtime checks for that group and it should not block vectorization. 8define void @test1_uncomputable_bounds_single_load(ptr noalias %ptr.1, ptr noalias %ptr.2, ptr noalias %ptr.3, i64 %N, i64 %X) { 9; CHECK-LABEL: define void @test1_uncomputable_bounds_single_load 10; CHECK: vector.body 11; CHECK: ret void 12 13entry: 14 %cond = icmp sgt i64 %N, 0 15 br i1 %cond, label %ph, label %exit 16 17ph: 18 br label %loop 19 20loop: 21 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 22 %gep.1 = getelementptr inbounds i32, ptr %ptr.3, i64 %iv 23 %offset.1 = load i32, ptr %gep.1, align 4 24 %gep.2 = getelementptr inbounds i32, ptr %ptr.2, i32 %offset.1 25 %lv = load i32, ptr %gep.2, align 4 26 %gep.3 = getelementptr inbounds i32, ptr %ptr.1, i64 %iv 27 store i32 %lv , ptr %gep.3, align 4 28 %offset.2 = add nsw i64 %iv, %X 29 %gep.4 = getelementptr inbounds i32, ptr %ptr.1, i64 %offset.2 30 store i32 %lv, ptr %gep.4, align 4 31 %iv.next = add nuw nsw i64 %iv, 1 32 %exitcond = icmp eq i64 %iv.next, %N 33 br i1 %exitcond, label %loop.exit, label %loop 34 35loop.exit: 36 br label %exit 37 38exit: 39 ret void 40} 41 42; Alias set with uncomputable bounds contains a single store. We do not need 43; runtime checks for that group and it should not block vectorization. 44define void @test2_uncomputable_bounds_single_store(ptr noalias %ptr.1, ptr noalias %ptr.2, ptr noalias %ptr.3, i64 %N, i64 %X) { 45; CHECK-LABEL: define void @test2_uncomputable_bounds_single_store 46; CHECK: vector.body 47; CHECK: ret void 48 49entry: 50 %cond = icmp sgt i64 %N, 0 51 br i1 %cond, label %ph, label %exit 52 53ph: 54 br label %loop 55 56loop: 57 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 58 %gep.1 = getelementptr inbounds i32, ptr %ptr.3, i64 %iv 59 %offset.1 = load i32, ptr %gep.1, align 4 60 %gep.2 = getelementptr inbounds i32, ptr %ptr.2, i32 %offset.1 61 store i32 20, ptr %gep.2, align 4 62 %gep.3 = getelementptr inbounds i32, ptr %ptr.1, i64 %iv 63 store i32 0 , ptr %gep.3, align 4 64 %offset.2 = add nsw i64 %iv, %X 65 %gep.4 = getelementptr inbounds i32, ptr %ptr.1, i64 %offset.2 66 store i32 10, ptr %gep.4, align 4 67 %iv.next = add nuw nsw i64 %iv, 1 68 %exitcond = icmp eq i64 %iv.next, %N 69 br i1 %exitcond, label %loop.exit, label %loop 70 71loop.exit: 72 br label %exit 73 74exit: 75 ret void 76} 77 78; Alias set with uncomputable bounds contains a load and a store. This blocks 79; vectorization, as we cannot generate runtime-checks for the set. 80define void @test3_uncomputable_bounds_load_store(ptr noalias %ptr.1, ptr noalias %ptr.2, ptr noalias %ptr.3, i64 %N, i64 %X) { 81; CHECK-LABEL: define void @test3_uncomputable_bounds_load_store 82; CHECK-NOT: vector.body 83 84entry: 85 %cond = icmp sgt i64 %N, 0 86 br i1 %cond, label %ph, label %exit 87 88ph: 89 br label %loop 90 91loop: 92 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 93 %gep.1 = getelementptr inbounds i32, ptr %ptr.3, i64 %iv 94 %offset.1 = load i32, ptr %gep.1, align 4 95 %gep.2 = getelementptr inbounds i32, ptr %ptr.2, i32 %offset.1 96 store i32 20, ptr %gep.2, align 4 97 %gep.22 = getelementptr inbounds i32, ptr %ptr.2, i64 %iv 98 %lv = load i32, ptr %gep.22, align 4 99 %gep.3 = getelementptr inbounds i32, ptr %ptr.1, i64 %iv 100 store i32 %lv , ptr %gep.3, align 4 101 %offset.2 = add nsw i64 %iv, %X 102 %gep.4 = getelementptr inbounds i32, ptr %ptr.1, i64 %offset.2 103 store i32 %lv, ptr %gep.4, align 4 104 %iv.next = add nuw nsw i64 %iv, 1 105 %exitcond = icmp eq i64 %iv.next, %N 106 br i1 %exitcond, label %loop.exit, label %loop 107 108loop.exit: 109 br label %exit 110 111exit: 112 ret void 113} 114 115; Alias set with uncomputable bounds contains a load and a store. This blocks 116; vectorization, as we cannot generate runtime-checks for the set. 117define void @test4_uncomputable_bounds_store_store(ptr noalias %ptr.1, ptr noalias %ptr.2, ptr noalias %ptr.3, i64 %N, i64 %X) { 118; CHECK-LABEL: define void @test4_uncomputable_bounds_store_store 119; CHECK-NOT: vector.body 120 121entry: 122 %cond = icmp sgt i64 %N, 0 123 br i1 %cond, label %ph, label %exit 124 125ph: 126 br label %loop 127 128loop: 129 %iv = phi i64 [ 0, %ph ], [ %iv.next, %loop ] 130 %gep.1 = getelementptr inbounds i32, ptr %ptr.3, i64 %iv 131 %offset.1 = load i32, ptr %gep.1, align 4 132 %gep.2 = getelementptr inbounds i32, ptr %ptr.2, i32 %offset.1 133 store i32 20, ptr %gep.2, align 4 134 %gep.22 = getelementptr inbounds i32, ptr %ptr.2, i64 %iv 135 store i32 30, ptr %gep.22, align 4 136 %gep.3 = getelementptr inbounds i32, ptr %ptr.1, i64 %iv 137 store i32 0 , ptr %gep.3, align 4 138 %offset.2 = add nsw i64 %iv, %X 139 %gep.4 = getelementptr inbounds i32, ptr %ptr.1, i64 %offset.2 140 store i32 10, ptr %gep.4, align 4 141 %iv.next = add nuw nsw i64 %iv, 1 142 %exitcond = icmp eq i64 %iv.next, %N 143 br i1 %exitcond, label %loop.exit, label %loop 144 145loop.exit: 146 br label %exit 147 148exit: 149 ret void 150} 151