1; RUN: opt -basic-aa -aa-eval -print-all-alias-modref-info %s 2>&1 | FileCheck %s 2 3; %col.ptr.1 and %col.ptr.2 do not alias, if we know that %skip >= 0, because 4; the distance between %col.ptr.1 and %col.ptr.2 is %skip + 6 and we load 6 5; elements. 6define void @test1(double* %ptr, i32 %skip) { 7; CHECK-LABEL: Function: test1: 4 pointers, 1 call sites 8; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.1, double* %ptr 9; CHECK-NEXT: NoAlias: double* %col.ptr.2, double* %ptr 10; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 11; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr 12; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast 13; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 14; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) 15; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) 16; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) 17; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) 18; 19 %gt = icmp sgt i32 %skip, -1 20 call void @llvm.assume(i1 %gt) 21 %stride = add nsw nuw i32 %skip, 6 22 %col.ptr.1 = bitcast double* %ptr to <6 x double>* 23 %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 24 %col.ptr.2= getelementptr double, double* %ptr, i32 %stride 25 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* 26 %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 27 %res.1 = fadd <6 x double> %lv.1, %lv.1 28 %res.2 = fadd <6 x double> %lv.2, %lv.2 29 store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8 30 store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8 31 ret void 32} 33 34; Same as @test1, but now we do not have an assume guaranteeing %skip >= 0. 35define void @test2(double* %ptr, i32 %skip) { 36; CHECK-LABEL: Function: test2: 4 pointers, 0 call sites 37; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.1, double* %ptr 38; CHECK-NEXT: MayAlias: double* %col.ptr.2, double* %ptr 39; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 40; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2.cast, double* %ptr 41; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast 42; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 43; 44 %stride = add nsw nuw i32 %skip, 6 45 %col.ptr.1 = bitcast double* %ptr to <6 x double>* 46 %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 47 %col.ptr.2= getelementptr double, double* %ptr, i32 %stride 48 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* 49 %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 50 %res.1 = fadd <6 x double> %lv.1, %lv.1 51 %res.2 = fadd <6 x double> %lv.2, %lv.2 52 store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8 53 store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8 54 ret void 55} 56 57; Same as @test1, but the assume just guarantees %skip > -3, which is not 58; enough to derive NoAlias 59define void @test3(double* %ptr, i32 %skip) { 60; CHECK-LABEL: Function: test3: 4 pointers, 1 call sites 61; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.1, double* %ptr 62; CHECK-NEXT: MayAlias: double* %col.ptr.2, double* %ptr 63; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 64; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.2.cast, double* %ptr 65; CHECK-NEXT: MayAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast 66; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 67; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) 68; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) 69; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) 70; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) 71; 72 %gt = icmp sgt i32 %skip, -3 73 call void @llvm.assume(i1 %gt) 74 %stride = add nsw nuw i32 %skip, 6 75 %col.ptr.1 = bitcast double* %ptr to <6 x double>* 76 %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 77 %col.ptr.2= getelementptr double, double* %ptr, i32 %stride 78 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* 79 %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 80 %res.1 = fadd <6 x double> %lv.1, %lv.1 81 %res.2 = fadd <6 x double> %lv.2, %lv.2 82 store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8 83 store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8 84 ret void 85} 86 87; Same as @test1, but the assume uses the sge predicate for %skip >= 0. 88define void @test4(double* %ptr, i32 %skip) { 89; CHECK-LABEL: Function: test4: 4 pointers, 1 call sites 90; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.1, double* %ptr 91; CHECK-NEXT: NoAlias: double* %col.ptr.2, double* %ptr 92; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2 93; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr 94; CHECK-NEXT: NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast 95; CHECK-NEXT: MustAlias: <6 x double>* %col.ptr.2.cast, double* %col.ptr.2 96; CHECK-NEXT: NoModRef: Ptr: double* %ptr <-> call void @llvm.assume(i1 %gt) 97; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.1 <-> call void @llvm.assume(i1 %gt) 98; CHECK-NEXT: NoModRef: Ptr: double* %col.ptr.2 <-> call void @llvm.assume(i1 %gt) 99; CHECK-NEXT: NoModRef: Ptr: <6 x double>* %col.ptr.2.cast <-> call void @llvm.assume(i1 %gt) 100; 101 %gt = icmp sge i32 %skip, 0 102 call void @llvm.assume(i1 %gt) 103 %stride = add nsw nuw i32 %skip, 6 104 %col.ptr.1 = bitcast double* %ptr to <6 x double>* 105 %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8 106 %col.ptr.2= getelementptr double, double* %ptr, i32 %stride 107 %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>* 108 %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8 109 %res.1 = fadd <6 x double> %lv.1, %lv.1 110 %res.2 = fadd <6 x double> %lv.2, %lv.2 111 store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8 112 store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8 113 ret void 114} 115 116declare void @llvm.assume(i1 %cond) 117