261 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S %s | FileCheck %s3 4define i32 @sink_load_that_uses_for_past_other_loads(ptr noalias %A, ptr noalias %B) {5; CHECK-LABEL: @sink_load_that_uses_for_past_other_loads(6; CHECK-NEXT: entry:7; CHECK-NEXT: br label [[LOOP:%.*]]8; CHECK: loop:9; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]10; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]11; CHECK-NEXT: [[RED:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[RED_NEXT:%.*]], [[LOOP]] ]12; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[FOR]]13; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 414; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[IV]]15; CHECK-NEXT: [[FOR_NEXT]] = load i32, ptr [[GEP_B]], align 416; CHECK-NEXT: [[ADD:%.*]] = add i32 [[FOR]], [[L_A]]17; CHECK-NEXT: [[RED_NEXT]] = add i32 [[RED]], [[ADD]]18; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 119; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 100020; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]21; CHECK: exit:22; CHECK-NEXT: [[RED_NEXT_LCSSA:%.*]] = phi i32 [ [[RED_NEXT]], [[LOOP]] ]23; CHECK-NEXT: ret i32 [[RED_NEXT_LCSSA]]24;25entry:26 br label %loop27 28loop:29 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]30 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]31 %red = phi i32 [ 0, %entry ], [ %red.next, %loop ]32 %gep.a = getelementptr inbounds i32, ptr %A, i32 %for33 %l.a = load i32, ptr %gep.a34 %gep.b = getelementptr inbounds i32, ptr %B, i32 %iv35 %for.next = load i32, ptr %gep.b36 %add = add i32 %for, %l.a37 %red.next = add i32 %red, %add38 %iv.next = add nuw nsw i32 %iv, 139 %ec = icmp eq i32 %iv.next, 100040 br i1 %ec, label %exit, label %loop41 42exit:43 ret i32 %red.next44}45 46define void @cannot_sink_load_past_mayalias_store(ptr noalias %A, ptr noalias %B) {47; CHECK-LABEL: @cannot_sink_load_past_mayalias_store(48; CHECK-NEXT: entry:49; CHECK-NEXT: br label [[LOOP:%.*]]50; CHECK: loop:51; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]52; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]53; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[FOR]]54; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 455; CHECK-NEXT: [[GEP_A_2:%.*]] = getelementptr inbounds i32, ptr [[A]], i32 [[IV]]56; CHECK-NEXT: [[ADD:%.*]] = add i32 [[FOR]], [[L_A]]57; CHECK-NEXT: store i32 [[ADD]], ptr [[GEP_A_2]], align 458; CHECK-NEXT: [[FOR_NEXT]] = load i32, ptr [[GEP_A_2]], align 459; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 160; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 100061; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]62; CHECK: exit:63; CHECK-NEXT: ret void64;65entry:66 br label %loop67 68loop:69 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]70 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]71 %gep.a = getelementptr inbounds i32, ptr %A, i32 %for72 %l.a = load i32, ptr %gep.a73 %gep.a.2 = getelementptr inbounds i32, ptr %A, i32 %iv74 %add = add i32 %for, %l.a75 store i32 %add, ptr %gep.a.276 %for.next = load i32, ptr %gep.a.277 %iv.next = add nuw nsw i32 %iv, 178 %ec = icmp eq i32 %iv.next, 100079 br i1 %ec, label %exit, label %loop80 81exit:82 ret void83}84 85define void @sink_store_that_uses_for_past_instructions(ptr noalias %A, ptr noalias %B) {86; CHECK-LABEL: @sink_store_that_uses_for_past_instructions(87; CHECK-NEXT: entry:88; CHECK-NEXT: br label [[LOOP:%.*]]89; CHECK: loop:90; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]91; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]92; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[IV]]93; CHECK-NEXT: store i32 [[FOR]], ptr [[GEP_A]], align 494; CHECK-NEXT: [[FOR_NEXT]] = add i32 [[IV]], 295; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 196; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 100097; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]98; CHECK: exit:99; CHECK-NEXT: ret void100;101entry:102 br label %loop103 104loop:105 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]106 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]107 %gep.a = getelementptr inbounds i32, ptr %A, i32 %iv108 store i32 %for, ptr %gep.a109 %for.next = add i32 %iv, 2110 %iv.next = add nuw nsw i32 %iv, 1111 %ec = icmp eq i32 %iv.next, 1000112 br i1 %ec, label %exit, label %loop113 114exit:115 ret void116}117 118define void @sink_store_past_non_aliasing_load(ptr noalias %A, ptr noalias %B) {119; CHECK-LABEL: @sink_store_past_non_aliasing_load(120; CHECK-NEXT: entry:121; CHECK-NEXT: br label [[LOOP:%.*]]122; CHECK: loop:123; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]124; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]125; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[IV]]126; CHECK-NEXT: store i32 [[FOR]], ptr [[GEP_A]], align 4127; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[IV]]128; CHECK-NEXT: [[FOR_NEXT]] = load i32, ptr [[GEP_B]], align 4129; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1130; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 1000131; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]132; CHECK: exit:133; CHECK-NEXT: ret void134;135entry:136 br label %loop137 138loop:139 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]140 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]141 %gep.a = getelementptr inbounds i32, ptr %A, i32 %iv142 store i32 %for, ptr %gep.a143 %gep.b = getelementptr inbounds i32, ptr %B, i32 %iv144 %for.next = load i32, ptr %gep.b145 %iv.next = add nuw nsw i32 %iv, 1146 %ec = icmp eq i32 %iv.next, 1000147 br i1 %ec, label %exit, label %loop148 149exit:150 ret void151}152 153define void @sink_store_past_aliasing_load(ptr %A, ptr %B) {154; CHECK-LABEL: @sink_store_past_aliasing_load(155; CHECK-NEXT: entry:156; CHECK-NEXT: br label [[LOOP:%.*]]157; CHECK: loop:158; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]159; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]160; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[IV]]161; CHECK-NEXT: store i32 [[FOR]], ptr [[GEP_A]], align 4162; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[IV]]163; CHECK-NEXT: [[FOR_NEXT]] = load i32, ptr [[GEP_B]], align 4164; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1165; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 1000166; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]167; CHECK: exit:168; CHECK-NEXT: ret void169;170entry:171 br label %loop172 173loop:174 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]175 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]176 %gep.a = getelementptr inbounds i32, ptr %A, i32 %iv177 store i32 %for, ptr %gep.a178 %gep.b = getelementptr inbounds i32, ptr %B, i32 %iv179 %for.next = load i32, ptr %gep.b180 %iv.next = add nuw nsw i32 %iv, 1181 %ec = icmp eq i32 %iv.next, 1000182 br i1 %ec, label %exit, label %loop183 184exit:185 ret void186}187 188define void @sink_store_past_non_aliasing_store(ptr noalias %A, ptr noalias %B) {189; CHECK-LABEL: @sink_store_past_non_aliasing_store(190; CHECK-NEXT: entry:191; CHECK-NEXT: br label [[LOOP:%.*]]192; CHECK: loop:193; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]194; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]195; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[IV]]196; CHECK-NEXT: store i32 [[FOR]], ptr [[GEP_A]], align 4197; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[IV]]198; CHECK-NEXT: store i32 123, ptr [[GEP_B]], align 4199; CHECK-NEXT: [[FOR_NEXT]] = add i32 [[IV]], 2200; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1201; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 1000202; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]203; CHECK: exit:204; CHECK-NEXT: ret void205;206entry:207 br label %loop208 209loop:210 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]211 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]212 %gep.a = getelementptr inbounds i32, ptr %A, i32 %iv213 store i32 %for, ptr %gep.a214 %gep.b = getelementptr inbounds i32, ptr %B, i32 %iv215 store i32 123, ptr %gep.b216 %for.next = add i32 %iv, 2217 %iv.next = add nuw nsw i32 %iv, 1218 %ec = icmp eq i32 %iv.next, 1000219 br i1 %ec, label %exit, label %loop220 221exit:222 ret void223}224 225define void @sink_store_past_aliasing_store(ptr %A, ptr %B) {226; CHECK-LABEL: @sink_store_past_aliasing_store(227; CHECK-NEXT: entry:228; CHECK-NEXT: br label [[LOOP:%.*]]229; CHECK: loop:230; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]231; CHECK-NEXT: [[FOR:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[FOR_NEXT:%.*]], [[LOOP]] ]232; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[IV]]233; CHECK-NEXT: store i32 [[FOR]], ptr [[GEP_A]], align 4234; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B:%.*]], i32 [[IV]]235; CHECK-NEXT: store i32 123, ptr [[GEP_B]], align 4236; CHECK-NEXT: [[FOR_NEXT]] = add i32 [[IV]], 2237; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1238; CHECK-NEXT: [[EC:%.*]] = icmp eq i32 [[IV_NEXT]], 1000239; CHECK-NEXT: br i1 [[EC]], label [[EXIT:%.*]], label [[LOOP]]240; CHECK: exit:241; CHECK-NEXT: ret void242;243entry:244 br label %loop245 246loop:247 %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]248 %for = phi i32 [ 0, %entry ], [ %for.next, %loop ]249 %gep.a = getelementptr inbounds i32, ptr %A, i32 %iv250 store i32 %for, ptr %gep.a251 %gep.b = getelementptr inbounds i32, ptr %B, i32 %iv252 store i32 123, ptr %gep.b253 %for.next = add i32 %iv, 2254 %iv.next = add nuw nsw i32 %iv, 1255 %ec = icmp eq i32 %iv.next, 1000256 br i1 %ec, label %exit, label %loop257 258exit:259 ret void260}261