246 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=newgvn -enable-phi-of-ops=true -S -o - %s | FileCheck %s3 4define void @hoisted-load(ptr %p, ptr %q) {5; CHECK-LABEL: @hoisted-load(6; CHECK-NEXT: bb56:7; CHECK-NEXT: [[N60:%.*]] = load i8, ptr [[P:%.*]], align 18; CHECK-NEXT: br label [[BB57:%.*]]9; CHECK: bb57:10; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ true, [[BB56:%.*]] ], [ [[N62:%.*]], [[BB229:%.*]] ]11; CHECK-NEXT: [[N59:%.*]] = phi i1 [ false, [[BB229]] ], [ true, [[BB56]] ]12; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ 0, [[BB56]] ], [ [[INC:%.*]], [[BB229]] ]13; CHECK-NEXT: [[N62]] = icmp ne i8 [[N60]], 214; CHECK-NEXT: br i1 [[PHIOFOPS]], label [[BB229]], label [[BB237:%.*]]15; CHECK: bb229:16; CHECK-NEXT: [[INC]] = add i8 [[IDX]], 117; CHECK-NEXT: store i8 [[INC]], ptr [[Q:%.*]], align 118; CHECK-NEXT: br label [[BB57]]19; CHECK: bb237:20; CHECK-NEXT: ret void21;22bb56:23 %n60 = load i8, ptr %p24 br label %bb5725 26bb57:27 %n59 = phi i1 [ false, %bb229 ], [ true, %bb56 ]28 %idx = phi i8 [0, %bb56], [%inc, %bb229]29 %n62 = icmp ne i8 %n60, 230 %n63 = or i1 %n59, %n6231 br i1 %n63, label %bb229, label %bb23732 33bb229:34 %inc = add i8 %idx, 135 store i8 %inc, ptr %q36 br label %bb5737 38bb237:39 ret void40}41 42define void @store-in-loop(ptr %p, ptr %q) {43; CHECK-LABEL: @store-in-loop(44; CHECK-NEXT: bb56:45; CHECK-NEXT: br label [[BB57:%.*]]46; CHECK: bb57:47; CHECK-NEXT: [[N59:%.*]] = phi i1 [ false, [[BB229:%.*]] ], [ true, [[BB56:%.*]] ]48; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ 0, [[BB56]] ], [ [[INC:%.*]], [[BB229]] ]49; CHECK-NEXT: [[N60:%.*]] = load i8, ptr [[P:%.*]], align 150; CHECK-NEXT: [[N62:%.*]] = icmp ne i8 [[N60]], 251; CHECK-NEXT: [[N63:%.*]] = or i1 [[N59]], [[N62]]52; CHECK-NEXT: br i1 [[N63]], label [[BB229]], label [[BB237:%.*]]53; CHECK: bb229:54; CHECK-NEXT: [[INC]] = add i8 [[IDX]], 155; CHECK-NEXT: store i8 [[INC]], ptr [[Q:%.*]], align 156; CHECK-NEXT: br label [[BB57]]57; CHECK: bb237:58; CHECK-NEXT: ret void59;60bb56:61 br label %bb5762 63bb57:64 %n59 = phi i1 [ false, %bb229 ], [ true, %bb56 ]65 %idx = phi i8 [0, %bb56], [%inc, %bb229]66 %n60 = load i8, ptr %p67 %n62 = icmp ne i8 %n60, 268 %n63 = or i1 %n59, %n6269 br i1 %n63, label %bb229, label %bb23770 71bb229:72 %inc = add i8 %idx, 173 store i8 %inc, ptr %q74 br label %bb5775 76bb237:77 ret void78}79 80; TODO: we should support this case81define void @no-alias-store-in-loop(ptr noalias %p, ptr noalias %q) {82; CHECK-LABEL: @no-alias-store-in-loop(83; CHECK-NEXT: bb56:84; CHECK-NEXT: br label [[BB57:%.*]]85; CHECK: bb57:86; CHECK-NEXT: [[N59:%.*]] = phi i1 [ false, [[BB229:%.*]] ], [ true, [[BB56:%.*]] ]87; CHECK-NEXT: [[IDX:%.*]] = phi i8 [ 0, [[BB56]] ], [ [[INC:%.*]], [[BB229]] ]88; CHECK-NEXT: [[N60:%.*]] = load i8, ptr [[P:%.*]], align 189; CHECK-NEXT: [[N62:%.*]] = icmp ne i8 [[N60]], 290; CHECK-NEXT: [[N63:%.*]] = or i1 [[N59]], [[N62]]91; CHECK-NEXT: br i1 [[N63]], label [[BB229]], label [[BB237:%.*]]92; CHECK: bb229:93; CHECK-NEXT: [[INC]] = add i8 [[IDX]], 194; CHECK-NEXT: store i8 [[INC]], ptr [[Q:%.*]], align 195; CHECK-NEXT: br label [[BB57]]96; CHECK: bb237:97; CHECK-NEXT: ret void98;99bb56:100 br label %bb57101 102bb57:103 %n59 = phi i1 [ false, %bb229 ], [ true, %bb56 ]104 %idx = phi i8 [0, %bb56], [%inc, %bb229]105 %n60 = load i8, ptr %p106 %n62 = icmp ne i8 %n60, 2107 %n63 = or i1 %n59, %n62108 br i1 %n63, label %bb229, label %bb237109 110bb229:111 %inc = add i8 %idx, 1112 store i8 %inc, ptr %q113 br label %bb57114 115bb237:116 ret void117}118 119define void @function-in-loop(ptr %p) {120; CHECK-LABEL: @function-in-loop(121; CHECK-NEXT: bb56:122; CHECK-NEXT: br label [[BB57:%.*]]123; CHECK: bb57:124; CHECK-NEXT: [[N59:%.*]] = phi i1 [ false, [[BB229:%.*]] ], [ true, [[BB56:%.*]] ]125; CHECK-NEXT: [[N60:%.*]] = load i8, ptr [[P:%.*]], align 1126; CHECK-NEXT: [[N62:%.*]] = icmp ne i8 [[N60]], 2127; CHECK-NEXT: [[N63:%.*]] = or i1 [[N59]], [[N62]]128; CHECK-NEXT: br i1 [[N63]], label [[BB229]], label [[BB237:%.*]]129; CHECK: bb229:130; CHECK-NEXT: call void @f()131; CHECK-NEXT: br label [[BB57]]132; CHECK: bb237:133; CHECK-NEXT: ret void134;135bb56:136 br label %bb57137 138bb57:139 %n59 = phi i1 [ false, %bb229 ], [ true, %bb56 ]140 %n60 = load i8, ptr %p141 %n62 = icmp ne i8 %n60, 2142 %n63 = or i1 %n59, %n62143 br i1 %n63, label %bb229, label %bb237144 145bb229:146 call void @f()147 br label %bb57148 149bb237:150 ret void151}152 153; TODO: we should support this case154define void @nowrite-function-in-loop(ptr %p) {155; CHECK-LABEL: @nowrite-function-in-loop(156; CHECK-NEXT: bb56:157; CHECK-NEXT: br label [[BB57:%.*]]158; CHECK: bb57:159; CHECK-NEXT: [[N59:%.*]] = phi i1 [ false, [[BB229:%.*]] ], [ true, [[BB56:%.*]] ]160; CHECK-NEXT: [[N60:%.*]] = load i8, ptr [[P:%.*]], align 1161; CHECK-NEXT: [[N62:%.*]] = icmp ne i8 [[N60]], 2162; CHECK-NEXT: [[N63:%.*]] = or i1 [[N59]], [[N62]]163; CHECK-NEXT: br i1 [[N63]], label [[BB229]], label [[BB237:%.*]]164; CHECK: bb229:165; CHECK-NEXT: call void @f() #[[ATTR0:[0-9]+]]166; CHECK-NEXT: br label [[BB57]]167; CHECK: bb237:168; CHECK-NEXT: ret void169;170bb56:171 br label %bb57172 173bb57:174 %n59 = phi i1 [ false, %bb229 ], [ true, %bb56 ]175 %n60 = load i8, ptr %p176 %n62 = icmp ne i8 %n60, 2177 %n63 = or i1 %n59, %n62178 br i1 %n63, label %bb229, label %bb237179 180bb229:181 call void @f() inaccessiblememonly182 br label %bb57183 184bb237:185 ret void186}187 188declare void @f()189 190define void @issfeoperand(ptr nocapture readonly %array, i1 %cond1, i1 %cond2, ptr nocapture readonly %p1, ptr nocapture writeonly %p2, ptr nocapture writeonly %p3) local_unnamed_addr #0 {191; CHECK-LABEL: @issfeoperand(192; CHECK-NEXT: for.body:193; CHECK-NEXT: br i1 [[COND1:%.*]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]194; CHECK: cond.true:195; CHECK-NEXT: [[ARRAYIDX31:%.*]] = getelementptr inbounds [3 x [2 x [1 x i8]]], ptr [[ARRAY:%.*]], i64 109, i64 0, i64 0, i64 undef196; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX31]], align 1197; CHECK-NEXT: br label [[COND_FALSE]]198; CHECK: cond.false:199; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[LD1]], [[COND_TRUE]] ], [ 0, [[FOR_BODY:%.*]] ]200; CHECK-NEXT: [[ARRAYIDX42:%.*]] = getelementptr inbounds [3 x [2 x [1 x i8]]], ptr [[ARRAY]], i64 109, i64 0, i64 0, i64 undef201; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX42]], align 1202; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[LD2]], [[PHI1]]203; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP1]] to i32204; CHECK-NEXT: store i32 [[ZEXT]], ptr [[P2:%.*]], align 4205; CHECK-NEXT: br i1 [[COND2:%.*]], label [[COND_END:%.*]], label [[EXIT:%.*]]206; CHECK: cond.end:207; CHECK-NEXT: [[LD3:%.*]] = load i16, ptr [[P1:%.*]], align 2208; CHECK-NEXT: [[SEXT:%.*]] = sext i16 [[LD3]] to i32209; CHECK-NEXT: br label [[EXIT]]210; CHECK: exit:211; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[SEXT]], [[COND_END]] ], [ 0, [[COND_FALSE]] ]212; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[LD2]], 0213; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP2]], i32 [[PHI2]], i32 0214; CHECK-NEXT: store i32 [[SEL]], ptr [[P3:%.*]], align 4215; CHECK-NEXT: ret void216;217for.body:218 br i1 %cond1, label %cond.true, label %cond.false219 220cond.true: ; preds = %for.body221 %arrayidx31 = getelementptr inbounds [3 x [2 x [1 x i8]]], ptr %array, i64 109, i64 0, i64 0, i64 undef222 %ld1 = load i8, ptr %arrayidx31, align 1223 br label %cond.false224 225cond.false: ; preds = %cond.true, %for.body226 %phi1 = phi i8 [ %ld1, %cond.true ], [ 0, %for.body ]227 %arrayidx42 = getelementptr inbounds [3 x [2 x [1 x i8]]], ptr %array, i64 109, i64 0, i64 0, i64 undef228 %ld2 = load i8, ptr %arrayidx42, align 1229 %cmp1 = icmp ult i8 %ld2, %phi1230 %zext = zext i1 %cmp1 to i32231 store i32 %zext, ptr %p2, align 4232 br i1 %cond2, label %cond.end, label %exit233 234cond.end: ; preds = %cond.false235 %ld3 = load i16, ptr %p1, align 2236 %sext = sext i16 %ld3 to i32237 br label %exit238 239exit: ; preds = %cond.end, %cond.false240 %phi2 = phi i32 [ %sext, %cond.end ], [ 0, %cond.false ]241 %cmp2 = icmp eq i8 %ld2, 0242 %sel = select i1 %cmp2, i32 %phi2, i32 0243 store i32 %sel, ptr %p3, align 4244 ret void245}246