180 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes='gvn' -basic-aa-separate-storage -S | FileCheck %s3 4declare void @llvm.assume(i1)5 6; Test basic queries.7 8define i8 @simple_no(ptr %p1, ptr %p2) {9; CHECK-LABEL: @simple_no(10; CHECK-NEXT: entry:11; CHECK-NEXT: store i8 0, ptr [[P1:%.*]], align 112; CHECK-NEXT: store i8 1, ptr [[P2:%.*]], align 113; CHECK-NEXT: [[LOADOFSTORE:%.*]] = load i8, ptr [[P1]], align 114; CHECK-NEXT: ret i8 [[LOADOFSTORE]]15;16entry:17 store i8 0, ptr %p118 store i8 1, ptr %p219 %loadofstore = load i8, ptr %p120 ret i8 %loadofstore21}22 23define i8 @simple_yes(ptr %p1, ptr %p2) {24; CHECK-LABEL: @simple_yes(25; CHECK-NEXT: entry:26; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1:%.*]], ptr [[P2:%.*]]) ]27; CHECK-NEXT: store i8 0, ptr [[P1]], align 128; CHECK-NEXT: store i8 1, ptr [[P2]], align 129; CHECK-NEXT: ret i8 030;31entry:32 call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]33 store i8 0, ptr %p134 store i8 1, ptr %p235 %loadofstore = load i8, ptr %p136 ret i8 %loadofstore37}38 39define i8 @ptr_to_ptr_no(ptr %pp) {40; CHECK-LABEL: @ptr_to_ptr_no(41; CHECK-NEXT: entry:42; CHECK-NEXT: [[P_BASE:%.*]] = load ptr, ptr [[PP:%.*]], align 843; CHECK-NEXT: store i8 0, ptr [[P_BASE]], align 144; CHECK-NEXT: [[P_BASE2:%.*]] = load ptr, ptr [[PP]], align 845; CHECK-NEXT: [[LOADOFSTORE:%.*]] = load i8, ptr [[P_BASE2]], align 146; CHECK-NEXT: ret i8 [[LOADOFSTORE]]47;48entry:49 %p_base = load ptr, ptr %pp50 store i8 0, ptr %p_base51 %p_base2 = load ptr, ptr %pp52 %loadofstore = load i8, ptr %p_base253 ret i8 %loadofstore54}55 56define i8 @ptr_to_ptr_yes(ptr %pp) {57; CHECK-LABEL: @ptr_to_ptr_yes(58; CHECK-NEXT: entry:59; CHECK-NEXT: [[P_BASE:%.*]] = load ptr, ptr [[PP:%.*]], align 860; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P_BASE]], ptr [[PP]]) ]61; CHECK-NEXT: store i8 0, ptr [[P_BASE]], align 162; CHECK-NEXT: ret i8 063;64entry:65 %p_base = load ptr, ptr %pp66 call void @llvm.assume(i1 1) ["separate_storage"(ptr %p_base, ptr %pp)]67 store i8 0, ptr %p_base68 %p_base2 = load ptr, ptr %pp69 %loadofstore = load i8, ptr %p_base270 ret i8 %loadofstore71}72 73; The analysis should only kick in if executed (or will be executed) at the74; given program point.75 76define i8 @flow_sensitive(ptr %p1, ptr %p2, i1 %cond) {77; CHECK-LABEL: @flow_sensitive(78; CHECK-NEXT: entry:79; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BRANCH:%.*]], label [[FALSE_BRANCH:%.*]]80; CHECK: true_branch:81; CHECK-NEXT: store i8 11, ptr [[P1:%.*]], align 182; CHECK-NEXT: store i8 22, ptr [[P2:%.*]], align 183; CHECK-NEXT: [[LOADOFSTORE_TRUE:%.*]] = load i8, ptr [[P1]], align 184; CHECK-NEXT: br label [[ENDIF:%.*]]85; CHECK: false_branch:86; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1]], ptr [[P2]]) ]87; CHECK-NEXT: store i8 33, ptr [[P1]], align 188; CHECK-NEXT: store i8 44, ptr [[P2]], align 189; CHECK-NEXT: br label [[ENDIF]]90; CHECK: endif:91; CHECK-NEXT: [[LOADOFSTORE:%.*]] = phi i8 [ [[LOADOFSTORE_TRUE]], [[TRUE_BRANCH]] ], [ 33, [[FALSE_BRANCH]] ]92; CHECK-NEXT: ret i8 [[LOADOFSTORE]]93;94entry:95 br i1 %cond, label %true_branch, label %false_branch96 97true_branch:98 store i8 11, ptr %p199 store i8 22, ptr %p2100 %loadofstore_true = load i8, ptr %p1101 br label %endif102 103false_branch:104 call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]105 store i8 33, ptr %p1106 store i8 44, ptr %p2107 %loadofstore_false = load i8, ptr %p1108 br label %endif109 110endif:111 %loadofstore = phi i8 [ %loadofstore_true, %true_branch ], [ %loadofstore_false, %false_branch ]112 ret i8 %loadofstore113}114 115define i8 @flow_sensitive_with_dominator(ptr %p1, ptr %p2, i1 %cond) {116; CHECK-LABEL: @flow_sensitive_with_dominator(117; CHECK-NEXT: entry:118; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[P1:%.*]], ptr [[P2:%.*]]) ]119; CHECK-NEXT: br i1 [[COND:%.*]], label [[TRUE_BRANCH:%.*]], label [[FALSE_BRANCH:%.*]]120; CHECK: true_branch:121; CHECK-NEXT: store i8 11, ptr [[P1]], align 1122; CHECK-NEXT: store i8 22, ptr [[P2]], align 1123; CHECK-NEXT: br label [[ENDIF:%.*]]124; CHECK: false_branch:125; CHECK-NEXT: store i8 33, ptr [[P1]], align 1126; CHECK-NEXT: store i8 44, ptr [[P2]], align 1127; CHECK-NEXT: br label [[ENDIF]]128; CHECK: endif:129; CHECK-NEXT: [[LOADOFSTORE:%.*]] = phi i8 [ 11, [[TRUE_BRANCH]] ], [ 33, [[FALSE_BRANCH]] ]130; CHECK-NEXT: ret i8 [[LOADOFSTORE]]131;132entry:133 call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]134 br i1 %cond, label %true_branch, label %false_branch135 136true_branch:137 store i8 11, ptr %p1138 store i8 22, ptr %p2139 %loadofstore_true = load i8, ptr %p1140 br label %endif141 142false_branch:143 store i8 33, ptr %p1144 store i8 44, ptr %p2145 %loadofstore_false = load i8, ptr %p1146 br label %endif147 148endif:149 %loadofstore = phi i8 [ %loadofstore_true, %true_branch ], [ %loadofstore_false, %false_branch ]150 ret i8 %loadofstore151}152 153; Hints are relative to entire regions of storage, not particular pointers154; inside them. We should know that the whole ranges are disjoint given hints at155; offsets.156 157define i8 @offset_agnostic(ptr %p1, ptr %p2) {158; CHECK-LABEL: @offset_agnostic(159; CHECK-NEXT: [[ACCESS1:%.*]] = getelementptr inbounds i8, ptr [[P1:%.*]], i64 12160; CHECK-NEXT: [[ACCESS2:%.*]] = getelementptr inbounds i8, ptr [[P2:%.*]], i64 34161; CHECK-NEXT: [[HINT1:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 56162; CHECK-NEXT: [[HINT2:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 78163; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[HINT1]], ptr [[HINT2]]) ]164; CHECK-NEXT: store i8 0, ptr [[ACCESS1]], align 1165; CHECK-NEXT: store i8 1, ptr [[ACCESS2]], align 1166; CHECK-NEXT: ret i8 0167;168 %access1 = getelementptr inbounds i8, ptr %p1, i64 12169 %access2 = getelementptr inbounds i8, ptr %p2, i64 34170 171 %hint1 = getelementptr inbounds i8, ptr %p1, i64 56172 %hint2 = getelementptr inbounds i8, ptr %p2, i64 78173 call void @llvm.assume(i1 1) ["separate_storage"(ptr %hint1, ptr %hint2)]174 175 store i8 0, ptr %access1176 store i8 1, ptr %access2177 %loadofstore = load i8, ptr %access1178 ret i8 %loadofstore179}180