diff --git a/llvm/lib/Transforms/Scalar/GuardWidening.cpp b/llvm/lib/Transforms/Scalar/GuardWidening.cpp --- a/llvm/lib/Transforms/Scalar/GuardWidening.cpp +++ b/llvm/lib/Transforms/Scalar/GuardWidening.cpp @@ -627,13 +627,23 @@ I->dropPoisonGeneratingFlagsAndMetadata(); Value *Result = Orig; + SmallPtrSet NeedFreezeSet(NeedFreeze.begin(), NeedFreeze.end()); for (Value *V : NeedFreeze) { auto *FreezeInsertPt = getFreezeInsertPt(V, DT); FreezeInst *FI = new FreezeInst(V, V->getName() + ".gw.fr", FreezeInsertPt); ++FreezeAdded; if (V == Orig) Result = FI; - V->replaceUsesWithIf(FI, [&](Use & U)->bool { return U.getUser() != FI; }); + if (isa(V) || isa(V)) + V->replaceUsesWithIf( + FI, [&](const Use & U)->bool { return U.getUser() != FI; }); + else + // if it is a constant or global, just make a change only in instructions + // we visited and which are not marked as NeedFreeze itself. + V->replaceUsesWithIf(FI, [&](const Use & U)->bool { + return U.getUser() != FI && Visited.contains(U) && + !NeedFreezeSet.count(U); + }); } return Result; diff --git a/llvm/test/Transforms/GuardWidening/hang.ll b/llvm/test/Transforms/GuardWidening/hang.ll --- a/llvm/test/Transforms/GuardWidening/hang.ll +++ b/llvm/test/Transforms/GuardWidening/hang.ll @@ -10,7 +10,7 @@ ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] ; CHECK-NEXT: br label [[BB2:%.*]] ; CHECK: bb2: -; CHECK-NEXT: br i1 [[DOTGW_FR]], label [[BB3:%.*]], label [[BB2]] +; CHECK-NEXT: br i1 poison, label [[BB3:%.*]], label [[BB2]] ; CHECK: bb3: ; CHECK-NEXT: [[CALL:%.*]] = call i64 (...) @llvm.experimental.deoptimize.i64() [ "deopt"() ] ; CHECK-NEXT: ret i64 [[CALL]] diff --git a/llvm/test/Transforms/GuardWidening/posion.ll b/llvm/test/Transforms/GuardWidening/posion.ll --- a/llvm/test/Transforms/GuardWidening/posion.ll +++ b/llvm/test/Transforms/GuardWidening/posion.ll @@ -219,3 +219,34 @@ %landing_pad = landingpad { ptr, i32 } cleanup ret void } + +declare void @dummy_vec(<4 x i1> %arg) + +define void @freeze_poison(i1 %c, i1 %g) { +; CHECK-LABEL: @freeze_poison( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[DOTGW_FR:%.*]] = freeze i1 poison +; CHECK-NEXT: br i1 [[C:%.*]], label [[LEFT:%.*]], label [[RIGHT:%.*]] +; CHECK: left: +; CHECK-NEXT: call void @dummy_vec(<4 x i1> ) +; CHECK-NEXT: ret void +; CHECK: right: +; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[G:%.*]], [[DOTGW_FR]] +; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ] +; CHECK-NEXT: ret void +; +entry: + br i1 %c, label %left, label %right + +left: + call void @dummy_vec(<4 x i1> ) + ret void + + +right: + call void (i1, ...) @llvm.experimental.guard(i1 %g) [ "deopt"() ] + call void (i1, ...) @llvm.experimental.guard(i1 poison) [ "deopt"() ] + ret void + +} +