diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -2803,6 +2803,8 @@ RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(I)); } + if (FoundVal != I) + addAdditionalUsers(FoundVal, I); PHIOps.push_back({FoundVal, PredBB}); LLVM_DEBUG(dbgs() << "Found phi of ops operand " << *FoundVal << " in " << getBlockName(PredBB) << "\n"); diff --git a/llvm/test/Transforms/NewGVN/pr36501-changed-after-3.ll b/llvm/test/Transforms/NewGVN/pr36501-changed-after-3.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/NewGVN/pr36501-changed-after-3.ll @@ -0,0 +1,172 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S < %s -newgvn | FileCheck %s + +; Test for PR36501. + +define void @func_1() local_unnamed_addr #0 { +; CHECK-LABEL: @func_1( +; CHECK-NEXT: br label [[TMP1:%.*]] +; CHECK: 1: +; CHECK-NEXT: [[DOT0:%.*]] = phi i32 [ -2022207984, [[TMP0:%.*]] ], [ 0, [[DOTLOOPEXIT_8:%.*]] ] +; CHECK-NEXT: br i1 undef, label [[TMP3:%.*]], label [[TMP2:%.*]] +; CHECK: 2: +; CHECK-NEXT: br label [[TMP3]] +; CHECK: 3: +; CHECK-NEXT: [[DOT1:%.*]] = phi i32 [ -1, [[TMP2]] ], [ [[DOT0]], [[TMP1]] ] +; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[DOT1]], 0 +; CHECK-NEXT: br i1 [[TMP4]], label [[DOTPREHEADER:%.*]], label [[DOTLOOPEXIT:%.*]] +; CHECK: .preheader: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH:%.*]], label [[DOTLOOPEXIT]] +; CHECK: .lr.ph: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH]], label [[DOTLOOPEXIT]] +; CHECK: .loopexit: +; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ [[TMP4]], [[TMP3]] ], [ true, [[DOTPREHEADER]] ], [ true, [[DOTLR_PH]] ] +; CHECK-NEXT: [[DOT4:%.*]] = phi i32 [ [[DOT1]], [[TMP3]] ], [ 0, [[DOTPREHEADER]] ], [ 0, [[DOTLR_PH]] ] +; CHECK-NEXT: br i1 [[PHIOFOPS]], label [[DOTPREHEADER_1:%.*]], label [[DOTLOOPEXIT_1:%.*]] +; CHECK: .preheader.1: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_1:%.*]], label [[DOTLOOPEXIT_1]] +; CHECK: .lr.ph.1: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_1]], label [[DOTLOOPEXIT_1]] +; CHECK: .loopexit.1: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_2:%.*]], label [[DOTLOOPEXIT_2:%.*]] +; CHECK: .preheader.2: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_2:%.*]], label [[DOTLOOPEXIT_2]] +; CHECK: .lr.ph.2: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_2]], label [[DOTLOOPEXIT_2]] +; CHECK: .loopexit.2: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_3:%.*]], label [[DOTLOOPEXIT_3:%.*]] +; CHECK: .preheader.3: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_3:%.*]], label [[DOTLOOPEXIT_3]] +; CHECK: .lr.ph.3: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_3]], label [[DOTLOOPEXIT_3]] +; CHECK: .loopexit.3: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_4:%.*]], label [[DOTLOOPEXIT_4:%.*]] +; CHECK: .preheader.4: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_4:%.*]], label [[DOTLOOPEXIT_4]] +; CHECK: .lr.ph.4: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_4]], label [[DOTLOOPEXIT_4]] +; CHECK: .loopexit.4: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_5:%.*]], label [[DOTLOOPEXIT_5:%.*]] +; CHECK: .preheader.5: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_5:%.*]], label [[DOTLOOPEXIT_5]] +; CHECK: .lr.ph.5: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_5]], label [[DOTLOOPEXIT_5]] +; CHECK: .loopexit.5: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_6:%.*]], label [[DOTLOOPEXIT_6:%.*]] +; CHECK: .preheader.6: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_6:%.*]], label [[DOTLOOPEXIT_6]] +; CHECK: .lr.ph.6: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_6]], label [[DOTLOOPEXIT_6]] +; CHECK: .loopexit.6: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_7:%.*]], label [[DOTLOOPEXIT_7:%.*]] +; CHECK: .preheader.7: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_7:%.*]], label [[DOTLOOPEXIT_7]] +; CHECK: .lr.ph.7: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_7]], label [[DOTLOOPEXIT_7]] +; CHECK: .loopexit.7: +; CHECK-NEXT: br i1 undef, label [[DOTPREHEADER_8:%.*]], label [[DOTLOOPEXIT_8]] +; CHECK: .preheader.8: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_8:%.*]], label [[DOTLOOPEXIT_8]] +; CHECK: .lr.ph.8: +; CHECK-NEXT: br i1 undef, label [[DOTLR_PH_8]], label [[DOTLOOPEXIT_8]] +; CHECK: .loopexit.8: +; CHECK-NEXT: br label [[TMP1]] +; + br label %1 + +1: ; preds = %.loopexit.8, %0 + %.0 = phi i32 [ -2022207984, %0 ], [ 0, %.loopexit.8 ] + %2 = icmp eq i16 undef, 0 + br i1 %2, label %4, label %3 + +3: ; preds = %1 + br label %4 + +4: ; preds = %3, %1 + %.1 = phi i32 [ -1, %3 ], [ %.0, %1 ] + %5 = icmp eq i32 %.1, 0 + br i1 %5, label %.preheader, label %.loopexit + +.preheader: ; preds = %4 + br i1 undef, label %.lr.ph, label %.loopexit + +.lr.ph: ; preds = %.lr.ph, %.preheader + br i1 undef, label %.lr.ph, label %.loopexit + +.loopexit: ; preds = %.lr.ph, %.preheader, %4 + %.4 = phi i32 [ %.1, %4 ], [ 0, %.preheader ], [ 0, %.lr.ph ] + %6 = icmp eq i32 %.4, 0 + br i1 %6, label %.preheader.1, label %.loopexit.1 + +.preheader.1: ; preds = %.loopexit + br i1 undef, label %.lr.ph.1, label %.loopexit.1 + +.lr.ph.1: ; preds = %.lr.ph.1, %.preheader.1 + br i1 undef, label %.lr.ph.1, label %.loopexit.1 + +.loopexit.1: ; preds = %.lr.ph.1, %.preheader.1, %.loopexit + br i1 undef, label %.preheader.2, label %.loopexit.2 + +.preheader.2: ; preds = %.loopexit.1 + br i1 undef, label %.lr.ph.2, label %.loopexit.2 + +.lr.ph.2: ; preds = %.lr.ph.2, %.preheader.2 + br i1 undef, label %.lr.ph.2, label %.loopexit.2 + +.loopexit.2: ; preds = %.lr.ph.2, %.preheader.2, %.loopexit.1 + br i1 undef, label %.preheader.3, label %.loopexit.3 + +.preheader.3: ; preds = %.loopexit.2 + br i1 undef, label %.lr.ph.3, label %.loopexit.3 + +.lr.ph.3: ; preds = %.lr.ph.3, %.preheader.3 + br i1 undef, label %.lr.ph.3, label %.loopexit.3 + +.loopexit.3: ; preds = %.lr.ph.3, %.preheader.3, %.loopexit.2 + br i1 undef, label %.preheader.4, label %.loopexit.4 + +.preheader.4: ; preds = %.loopexit.3 + br i1 undef, label %.lr.ph.4, label %.loopexit.4 + +.lr.ph.4: ; preds = %.lr.ph.4, %.preheader.4 + br i1 undef, label %.lr.ph.4, label %.loopexit.4 + +.loopexit.4: ; preds = %.lr.ph.4, %.preheader.4, %.loopexit.3 + br i1 undef, label %.preheader.5, label %.loopexit.5 + +.preheader.5: ; preds = %.loopexit.4 + br i1 undef, label %.lr.ph.5, label %.loopexit.5 + +.lr.ph.5: ; preds = %.lr.ph.5, %.preheader.5 + br i1 undef, label %.lr.ph.5, label %.loopexit.5 + +.loopexit.5: ; preds = %.lr.ph.5, %.preheader.5, %.loopexit.4 + br i1 undef, label %.preheader.6, label %.loopexit.6 + +.preheader.6: ; preds = %.loopexit.5 + br i1 undef, label %.lr.ph.6, label %.loopexit.6 + +.lr.ph.6: ; preds = %.lr.ph.6, %.preheader.6 + br i1 undef, label %.lr.ph.6, label %.loopexit.6 + +.loopexit.6: ; preds = %.lr.ph.6, %.preheader.6, %.loopexit.5 + br i1 undef, label %.preheader.7, label %.loopexit.7 + +.preheader.7: ; preds = %.loopexit.6 + br i1 undef, label %.lr.ph.7, label %.loopexit.7 + +.lr.ph.7: ; preds = %.lr.ph.7, %.preheader.7 + br i1 undef, label %.lr.ph.7, label %.loopexit.7 + +.loopexit.7: ; preds = %.lr.ph.7, %.preheader.7, %.loopexit.6 + br i1 undef, label %.preheader.8, label %.loopexit.8 + +.preheader.8: ; preds = %.loopexit.7 + br i1 undef, label %.lr.ph.8, label %.loopexit.8 + +.lr.ph.8: ; preds = %.lr.ph.8, %.preheader.8 + br i1 undef, label %.lr.ph.8, label %.loopexit.8 + +.loopexit.8: ; preds = %.lr.ph.8, %.preheader.8, %.loopexit.7 + br label %1 +} diff --git a/llvm/test/Transforms/NewGVN/pr42422-changed-after-2.ll b/llvm/test/Transforms/NewGVN/pr42422-changed-after-2.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/NewGVN/pr42422-changed-after-2.ll @@ -0,0 +1,143 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -newgvn < %s | FileCheck %s + +; Test for PR42422. + +define void @d() { +; CHECK-LABEL: @d( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: br label [[FOR_COND1:%.*]] +; CHECK: for.cond1: +; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[INC18:%.*]], [[FOR_INC17:%.*]] ], [ 0, [[FOR_COND]] ] +; CHECK-NEXT: [[CMP:%.*]] = icmp sle i32 [[TMP0]], 1 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END19:%.*]] +; CHECK: for.body: +; CHECK-NEXT: br i1 undef, label [[FOR_BODY3:%.*]], label [[FOR_BODY_FOR_COND4_CRIT_EDGE:%.*]] +; CHECK: for.body.for.cond4_crit_edge: +; CHECK-NEXT: br label [[FOR_COND4:%.*]] +; CHECK: for.body3: +; CHECK-NEXT: br label [[CLEANUP14:%.*]] +; CHECK: for.cond4: +; CHECK-NEXT: br i1 undef, label [[IF_THEN:%.*]], label [[IF_END:%.*]] +; CHECK: if.then: +; CHECK-NEXT: br label [[CLEANUP:%.*]] +; CHECK: if.end: +; CHECK-NEXT: br label [[FOR_COND6:%.*]] +; CHECK: for.cond6: +; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[IF_END]] ] +; CHECK-NEXT: [[CMP7:%.*]] = icmp sle i64 [[TMP1]], 1 +; CHECK-NEXT: br i1 [[CMP7]], label [[FOR_INC]], label [[FOR_END9:%.*]] +; CHECK: for.inc: +; CHECK-NEXT: [[INC]] = add nsw i64 [[TMP1]], 1 +; CHECK-NEXT: br label [[FOR_COND6]] +; CHECK: for.end9: +; CHECK-NEXT: br i1 true, label [[IF_THEN11:%.*]], label [[IF_END12:%.*]] +; CHECK: if.then11: +; CHECK-NEXT: br label [[CLEANUP]] +; CHECK: if.end12: +; CHECK-NEXT: store i8 undef, i8* null +; CHECK-NEXT: br label [[CLEANUP]] +; CHECK: cleanup: +; CHECK-NEXT: [[CLEANUP_DEST:%.*]] = phi i32 [ undef, [[IF_END12]] ], [ 1, [[IF_THEN11]] ], [ 9, [[IF_THEN]] ] +; CHECK-NEXT: switch i32 [[CLEANUP_DEST]], label [[CLEANUP14]] [ +; CHECK-NEXT: i32 0, label [[FOR_COND4]] +; CHECK-NEXT: i32 9, label [[FOR_END13:%.*]] +; CHECK-NEXT: ] +; CHECK: for.end13: +; CHECK-NEXT: br label [[CLEANUP14]] +; CHECK: cleanup14: +; CHECK-NEXT: [[CLEANUP_DEST15:%.*]] = phi i32 [ 0, [[FOR_END13]] ], [ [[CLEANUP_DEST]], [[CLEANUP]] ], [ 1, [[FOR_BODY3]] ] +; CHECK-NEXT: [[COND1:%.*]] = icmp eq i32 [[CLEANUP_DEST15]], 0 +; CHECK-NEXT: br i1 [[COND1]], label [[FOR_INC17]], label [[CLEANUP20:%.*]] +; CHECK: for.inc17: +; CHECK-NEXT: [[INC18]] = add nsw i32 [[TMP0]], 1 +; CHECK-NEXT: br label [[FOR_COND1]] +; CHECK: for.end19: +; CHECK-NEXT: br label [[CLEANUP20]] +; CHECK: cleanup20: +; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ true, [[FOR_END19]] ], [ [[COND1]], [[CLEANUP14]] ] +; CHECK-NEXT: [[CLEANUP_DEST21:%.*]] = phi i32 [ [[CLEANUP_DEST15]], [[CLEANUP14]] ], [ 0, [[FOR_END19]] ] +; CHECK-NEXT: br i1 [[PHIOFOPS]], label [[FOR_COND]], label [[CLEANUP23:%.*]] +; CHECK: cleanup23: +; CHECK-NEXT: ret void +; +entry: + br label %for.cond + +for.cond: ; preds = %cleanup20, %entry + br label %for.cond1 + +for.cond1: ; preds = %for.inc17, %for.cond + %0 = phi i32 [ %inc18, %for.inc17 ], [ 0, %for.cond ] + %cmp = icmp sle i32 %0, 1 + br i1 %cmp, label %for.body, label %for.end19 + +for.body: ; preds = %for.cond1 + %tobool = icmp ne i32 undef, 0 + br i1 %tobool, label %for.body3, label %for.body.for.cond4_crit_edge + +for.body.for.cond4_crit_edge: ; preds = %for.body + br label %for.cond4 + +for.body3: ; preds = %for.body + br label %cleanup14 + +for.cond4: ; preds = %cleanup, %for.body.for.cond4_crit_edge + br i1 undef, label %if.then, label %if.end + +if.then: ; preds = %for.cond4 + br label %cleanup + +if.end: ; preds = %for.cond4 + br label %for.cond6 + +for.cond6: ; preds = %for.inc, %if.end + %1 = phi i64 [ %inc, %for.inc ], [ 0, %if.end ] + %cmp7 = icmp sle i64 %1, 1 + br i1 %cmp7, label %for.inc, label %for.end9 + +for.inc: ; preds = %for.cond6 + %inc = add nsw i64 %1, 1 + br label %for.cond6 + +for.end9: ; preds = %for.cond6 + br i1 true, label %if.then11, label %if.end12 + +if.then11: ; preds = %for.end9 + br label %cleanup + +if.end12: ; preds = %for.end9 + br label %cleanup + +cleanup: ; preds = %if.end12, %if.then11, %if.then + %cleanup.dest = phi i32 [ undef, %if.end12 ], [ 1, %if.then11 ], [ 9, %if.then ] + switch i32 %cleanup.dest, label %cleanup14 [ + i32 0, label %for.cond4 + i32 9, label %for.end13 + ] + +for.end13: ; preds = %cleanup + br label %cleanup14 + +cleanup14: ; preds = %for.end13, %cleanup, %for.body3 + %cleanup.dest15 = phi i32 [ 0, %for.end13 ], [ %cleanup.dest, %cleanup ], [ 1, %for.body3 ] + %cond1 = icmp eq i32 %cleanup.dest15, 0 + br i1 %cond1, label %for.inc17, label %cleanup20 + +for.inc17: ; preds = %cleanup14 + %inc18 = add nsw i32 %0, 1 + br label %for.cond1 + +for.end19: ; preds = %for.cond1 + br label %cleanup20 + +cleanup20: ; preds = %for.end19, %cleanup14 + %cleanup.dest21 = phi i32 [ %cleanup.dest15, %cleanup14 ], [ 0, %for.end19 ] + %cond = icmp eq i32 %cleanup.dest21, 0 + br i1 %cond, label %for.cond, label %cleanup23 + +cleanup23: ; preds = %cleanup20 + ret void +} diff --git a/llvm/test/Transforms/NewGVN/pr42557-changed-after-1.ll b/llvm/test/Transforms/NewGVN/pr42557-changed-after-1.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/NewGVN/pr42557-changed-after-1.ll @@ -0,0 +1,68 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -newgvn < %s | FileCheck %s + +; Test for PR42557. + +declare void @use1(i1) +declare i1 @get1() + +define void @hoge(i32 %tmp6) { +; CHECK-LABEL: @hoge( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[A:%.*]] = call i1 @get1() +; CHECK-NEXT: [[B:%.*]] = call i1 @get1() +; CHECK-NEXT: br label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP6:%.*]], [[BB1]] ] +; CHECK-NEXT: br i1 [[A]], label [[BB2:%.*]], label [[BB1]] +; CHECK: bb2: +; CHECK-NEXT: br i1 [[B]], label [[BB16:%.*]], label [[BB11:%.*]] +; CHECK: bb16: +; CHECK-NEXT: [[TMP17:%.*]] = add i32 [[TMP]], 1 +; CHECK-NEXT: br label [[BB11]] +; CHECK: bb11: +; CHECK-NEXT: [[TMP12:%.*]] = phi i32 [ [[TMP17]], [[BB16]] ], [ 0, [[BB2]] ] +; CHECK-NEXT: [[TMP13:%.*]] = icmp eq i32 [[TMP12]], 0 +; CHECK-NEXT: call void @use1(i1 [[TMP13]]) +; CHECK-NEXT: [[TMP15:%.*]] = icmp ne i32 [[TMP]], 0 +; CHECK-NEXT: br i1 [[TMP15]], label [[BB18:%.*]], label [[BB19:%.*]] +; CHECK: bb18: +; CHECK-NEXT: br label [[BB19]] +; CHECK: bb19: +; CHECK-NEXT: [[PHIOFOPS:%.*]] = phi i1 [ [[TMP13]], [[BB11]] ], [ false, [[BB18]] ] +; CHECK-NEXT: [[TMP20:%.*]] = phi i32 [ [[TMP12]], [[BB11]] ], [ 1, [[BB18]] ] +; CHECK-NEXT: call void @use1(i1 [[PHIOFOPS]]) +; CHECK-NEXT: ret void +; +bb: + %A = call i1 @get1() + %B = call i1 @get1() + br label %bb1 + +bb1: ; preds = %bb1, %bb + %tmp = phi i32 [ 0, %bb ], [ %tmp6, %bb1 ] + br i1 %A, label %bb2, label %bb1 + +bb2: ; preds = %bb1 + br i1 %B, label %bb16, label %bb11 + +bb16: ; preds = %bb2 + %tmp17 = add i32 %tmp, 1 + br label %bb11 + +bb11: ; preds = %bb16, %bb2 + %tmp12 = phi i32 [ %tmp17, %bb16 ], [ 0, %bb2 ] + %tmp13 = icmp eq i32 %tmp12, 0 + call void @use1(i1 %tmp13) + %tmp15 = icmp ne i32 %tmp, 0 + br i1 %tmp15, label %bb18, label %bb19 + +bb18: ; preds = %bb11 + br label %bb19 + +bb19: ; preds = %bb18, %bb11 + %tmp20 = phi i32 [ %tmp12, %bb11 ], [ 1, %bb18 ] + %tmp21 = icmp eq i32 %tmp20, 0 + call void @use1(i1 %tmp21) + ret void +}