1target datalayout = 2"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3 4; RUN: opt < %s -basic-aa -aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s 5 6; ptr_phi and ptr2_phi do not alias. 7; CHECK: test_noalias_1 8; CHECK: NoAlias: i32* %ptr2_phi, i32* %ptr_phi 9; CHECK: MayAlias: i32* %ptr2_inc, i32* %ptr_inc 10; TODO: The incs should also be NoAlias. 11define i32 @test_noalias_1(i32* %ptr2, i32 %count, i32* %coeff) { 12entry: 13 %ptr = getelementptr inbounds i32, i32* %ptr2, i64 1 14 br label %while.body 15 16while.body: 17 %num = phi i32 [ %count, %entry ], [ %dec, %while.body ] 18 %ptr_phi = phi i32* [ %ptr, %entry ], [ %ptr_inc, %while.body ] 19 %ptr2_phi = phi i32* [ %ptr2, %entry ], [ %ptr2_inc, %while.body ] 20 %result.09 = phi i32 [ 0 , %entry ], [ %add, %while.body ] 21 %dec = add nsw i32 %num, -1 22 %0 = load i32, i32* %ptr_phi, align 4 23 store i32 %0, i32* %ptr2_phi, align 4 24 %1 = load i32, i32* %coeff, align 4 25 %2 = load i32, i32* %ptr_phi, align 4 26 %mul = mul nsw i32 %1, %2 27 %add = add nsw i32 %mul, %result.09 28 %tobool = icmp eq i32 %dec, 0 29 %ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1 30 %ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 31 br i1 %tobool, label %the_exit, label %while.body 32 33the_exit: 34 ret i32 %add 35} 36 37; CHECK: test_noalias_2 38; CHECK: NoAlias: i32* %ptr_outer_phi, i32* %ptr_outer_phi2 39; CHECK: MayAlias: i32* %ptr2_inc_outer, i32* %ptr_inc_outer 40; CHECK: NoAlias: i32* %ptr2_phi, i32* %ptr_phi 41; CHECK: MayAlias: i32* %ptr2_inc, i32* %ptr_inc 42; TODO: The incs should also be NoAlias. 43define i32 @test_noalias_2(i32* %ptr2, i32 %count, i32* %coeff) { 44entry: 45 %ptr = getelementptr inbounds i32, i32* %ptr2, i64 1 46 br label %outer.while.header 47 48outer.while.header: 49 %ptr_outer_phi = phi i32* [%ptr_inc_outer, %outer.while.backedge], [ %ptr, %entry] 50 %ptr_outer_phi2 = phi i32* [%ptr2_inc_outer, %outer.while.backedge], [ %ptr2, %entry] 51 %num.outer = phi i32 [ %count, %entry ], [ %dec.outer, %outer.while.backedge ] 52 br label %while.body 53 54while.body: 55 %num = phi i32 [ %count, %outer.while.header ], [ %dec, %while.body ] 56 %ptr_phi = phi i32* [ %ptr_outer_phi, %outer.while.header ], [ %ptr_inc, %while.body ] 57 %ptr2_phi = phi i32* [ %ptr_outer_phi2, %outer.while.header ], [ %ptr2_inc, %while.body ] 58 %result.09 = phi i32 [ 0 , %outer.while.header ], [ %add, %while.body ] 59 %dec = add nsw i32 %num, -1 60 %0 = load i32, i32* %ptr_phi, align 4 61 store i32 %0, i32* %ptr2_phi, align 4 62 %1 = load i32, i32* %coeff, align 4 63 %2 = load i32, i32* %ptr_phi, align 4 64 %mul = mul nsw i32 %1, %2 65 %add = add nsw i32 %mul, %result.09 66 %tobool = icmp eq i32 %dec, 0 67 %ptr_inc = getelementptr inbounds i32, i32* %ptr_phi, i64 1 68 %ptr2_inc = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 69 br i1 %tobool, label %outer.while.backedge, label %while.body 70 71outer.while.backedge: 72 %ptr_inc_outer = getelementptr inbounds i32, i32* %ptr_phi, i64 1 73 %ptr2_inc_outer = getelementptr inbounds i32, i32* %ptr2_phi, i64 1 74 %dec.outer = add nsw i32 %num.outer, -1 75 %br.cond = icmp eq i32 %dec.outer, 0 76 br i1 %br.cond, label %the_exit, label %outer.while.header 77 78the_exit: 79 ret i32 %add 80} 81 82; CHECK: test_noalias_3 83; CHECK: MayAlias: i8* %ptr2_phi, i8* %ptr_phi 84define i32 @test_noalias_3(i8* noalias %x, i8* noalias %y, i8* noalias %z, 85 i32 %count) { 86entry: 87 br label %while.body 88 89while.body: 90 %num = phi i32 [ %count, %entry ], [ %dec, %while.body ] 91 %ptr_phi = phi i8* [ %x, %entry ], [ %z, %while.body ] 92 %ptr2_phi = phi i8* [ %y, %entry ], [ %ptr_phi, %while.body ] 93 %dec = add nsw i32 %num, -1 94 %tobool = icmp eq i32 %dec, 0 95 br i1 %tobool, label %the_exit, label %while.body 96 97the_exit: 98 ret i32 1 99} 100 101; CHECK-LABEL: test_different_stride_noalias 102; CHECK: NoAlias: i16* %y.base, i8* %x.base 103; CHECK: NoAlias: i16* %y, i8* %x 104; CHECK: NoAlias: i16* %y.next, i8* %x.next 105define void @test_different_stride_noalias(i1 %c, i8* noalias %x.base, i16* noalias %y.base) { 106entry: 107 br label %loop 108 109loop: 110 %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] 111 %y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ] 112 %x.next = getelementptr i8, i8* %x, i64 1 113 %y.next = getelementptr i16, i16* %y, i64 1 114 br i1 %c, label %loop, label %exit 115 116exit: 117 ret void 118} 119 120; CHECK-LABEL: test_no_loop_mustalias 121; CHECK: MayAlias: i16* %z16, i8* %z8 122; TODO: (z8, z16) could be MustAlias 123define void @test_no_loop_mustalias(i1 %c, i8* noalias %x8, i8* noalias %y8) { 124 br i1 %c, label %if, label %else 125 126if: 127 %x16 = bitcast i8* %x8 to i16* 128 br label %end 129 130else: 131 %y16 = bitcast i8* %y8 to i16* 132 br label %end 133 134end: 135 %z8 = phi i8* [ %x8, %if ], [ %y8, %else ] 136 %z16 = phi i16* [ %x16, %if ], [ %y16, %else ] 137 ret void 138} 139 140; CHECK-LABEL: test_same_stride_mustalias 141; CHECK: MustAlias: i4* %y.base, i8* %x.base 142; CHECK: MayAlias: i4* %y, i8* %x 143; CHECK: MayAlias: i4* %y.next, i8* %x.next 144; TODO: (x, y) could be MustAlias 145define void @test_same_stride_mustalias(i1 %c, i8* noalias %x.base) { 146entry: 147 %y.base = bitcast i8* %x.base to i4* 148 br label %loop 149 150loop: 151 %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] 152 %y = phi i4* [ %y.base, %entry ], [ %y.next, %loop ] 153 %x.next = getelementptr i8, i8* %x, i64 1 154 %y.next = getelementptr i4, i4* %y, i64 1 155 br i1 %c, label %loop, label %exit 156 157exit: 158 ret void 159} 160 161; CHECK-LABEL: test_different_stride_mustalias 162; CHECK: MustAlias: i16* %y.base, i8* %x.base 163; CHECK: MayAlias: i16* %y, i8* %x 164; CHECK: MayAlias: i16* %y.next, i8* %x.next 165; Even though the base pointers MustAlias, the different strides don't preserve 166; this property across iterations. 167define void @test_different_stride_mustalias(i1 %c, i8* noalias %x.base) { 168entry: 169 %y.base = bitcast i8* %x.base to i16* 170 br label %loop 171 172loop: 173 %x = phi i8* [ %x.base, %entry ], [ %x.next, %loop ] 174 %y = phi i16* [ %y.base, %entry ], [ %y.next, %loop ] 175 %x.next = getelementptr i8, i8* %x, i64 1 176 %y.next = getelementptr i16, i16* %y, i64 1 177 br i1 %c, label %loop, label %exit 178 179exit: 180 ret void 181} 182