-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ValueTracking] Take PHI's poison-generating flags into account #161530
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) Changesninf/nnan in the phi node may produce poison values. They should be considered in Full diff: https://github.com/llvm/llvm-project/pull/161530.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6f11b250cf21f..09a8fbea065ac 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7651,25 +7651,26 @@ static bool isGuaranteedNotToBeUndefOrPoison(
return true;
}
- if (const auto *PN = dyn_cast<PHINode>(V)) {
- unsigned Num = PN->getNumIncomingValues();
- bool IsWellDefined = true;
- for (unsigned i = 0; i < Num; ++i) {
- if (PN == PN->getIncomingValue(i))
- continue;
- auto *TI = PN->getIncomingBlock(i)->getTerminator();
- if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
- DT, Depth + 1, Kind)) {
- IsWellDefined = false;
- break;
+ if (!::canCreateUndefOrPoison(Opr, Kind,
+ /*ConsiderFlagsAndMetadata=*/true)) {
+ if (const auto *PN = dyn_cast<PHINode>(V)) {
+ unsigned Num = PN->getNumIncomingValues();
+ bool IsWellDefined = true;
+ for (unsigned i = 0; i < Num; ++i) {
+ if (PN == PN->getIncomingValue(i))
+ continue;
+ auto *TI = PN->getIncomingBlock(i)->getTerminator();
+ if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
+ DT, Depth + 1, Kind)) {
+ IsWellDefined = false;
+ break;
+ }
}
- }
- if (IsWellDefined)
+ if (IsWellDefined)
+ return true;
+ } else if (all_of(Opr->operands(), OpCheck))
return true;
- } else if (!::canCreateUndefOrPoison(Opr, Kind,
- /*ConsiderFlagsAndMetadata*/ true) &&
- all_of(Opr->operands(), OpCheck))
- return true;
+ }
}
if (auto *I = dyn_cast<LoadInst>(V))
diff --git a/llvm/test/Transforms/InstCombine/freeze-phi.ll b/llvm/test/Transforms/InstCombine/freeze-phi.ll
index cdc9a5efe5933..62bb9dc31b76b 100644
--- a/llvm/test/Transforms/InstCombine/freeze-phi.ll
+++ b/llvm/test/Transforms/InstCombine/freeze-phi.ll
@@ -212,3 +212,31 @@ D:
%y.fr = freeze i32 %y
ret i32 %y.fr
}
+
+; Make sure that fmf in phi node is dropped when freeze get folded.
+
+define float @pr161524(float noundef %arg) {
+; CHECK-LABEL: @pr161524(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COND:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 144)
+; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_EXIT:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: [[FADD:%.*]] = fadd float [[ARG]], 1.000000e+00
+; CHECK-NEXT: br label [[IF_EXIT]]
+; CHECK: if.exit:
+; CHECK-NEXT: [[RET:%.*]] = phi float [ [[FADD]], [[IF_THEN]] ], [ [[ARG]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: ret float [[RET]]
+;
+entry:
+ %cond = tail call i1 @llvm.is.fpclass.f32(float %arg, i32 144)
+ br i1 %cond, label %if.then, label %if.exit
+
+if.then:
+ %fadd = fadd float %arg, 1.0
+ br label %if.exit
+
+if.exit:
+ %ret = phi ninf float [ %fadd, %if.then ], [ %arg, %entry ]
+ %ret.fr = freeze float %ret
+ ret float %ret.fr
+}
|
@llvm/pr-subscribers-llvm-analysis Author: Yingwei Zheng (dtcxzyw) Changesninf/nnan in the phi node may produce poison values. They should be considered in Full diff: https://github.com/llvm/llvm-project/pull/161530.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 6f11b250cf21f..09a8fbea065ac 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7651,25 +7651,26 @@ static bool isGuaranteedNotToBeUndefOrPoison(
return true;
}
- if (const auto *PN = dyn_cast<PHINode>(V)) {
- unsigned Num = PN->getNumIncomingValues();
- bool IsWellDefined = true;
- for (unsigned i = 0; i < Num; ++i) {
- if (PN == PN->getIncomingValue(i))
- continue;
- auto *TI = PN->getIncomingBlock(i)->getTerminator();
- if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
- DT, Depth + 1, Kind)) {
- IsWellDefined = false;
- break;
+ if (!::canCreateUndefOrPoison(Opr, Kind,
+ /*ConsiderFlagsAndMetadata=*/true)) {
+ if (const auto *PN = dyn_cast<PHINode>(V)) {
+ unsigned Num = PN->getNumIncomingValues();
+ bool IsWellDefined = true;
+ for (unsigned i = 0; i < Num; ++i) {
+ if (PN == PN->getIncomingValue(i))
+ continue;
+ auto *TI = PN->getIncomingBlock(i)->getTerminator();
+ if (!isGuaranteedNotToBeUndefOrPoison(PN->getIncomingValue(i), AC, TI,
+ DT, Depth + 1, Kind)) {
+ IsWellDefined = false;
+ break;
+ }
}
- }
- if (IsWellDefined)
+ if (IsWellDefined)
+ return true;
+ } else if (all_of(Opr->operands(), OpCheck))
return true;
- } else if (!::canCreateUndefOrPoison(Opr, Kind,
- /*ConsiderFlagsAndMetadata*/ true) &&
- all_of(Opr->operands(), OpCheck))
- return true;
+ }
}
if (auto *I = dyn_cast<LoadInst>(V))
diff --git a/llvm/test/Transforms/InstCombine/freeze-phi.ll b/llvm/test/Transforms/InstCombine/freeze-phi.ll
index cdc9a5efe5933..62bb9dc31b76b 100644
--- a/llvm/test/Transforms/InstCombine/freeze-phi.ll
+++ b/llvm/test/Transforms/InstCombine/freeze-phi.ll
@@ -212,3 +212,31 @@ D:
%y.fr = freeze i32 %y
ret i32 %y.fr
}
+
+; Make sure that fmf in phi node is dropped when freeze get folded.
+
+define float @pr161524(float noundef %arg) {
+; CHECK-LABEL: @pr161524(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COND:%.*]] = tail call i1 @llvm.is.fpclass.f32(float [[ARG:%.*]], i32 144)
+; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_EXIT:%.*]]
+; CHECK: if.then:
+; CHECK-NEXT: [[FADD:%.*]] = fadd float [[ARG]], 1.000000e+00
+; CHECK-NEXT: br label [[IF_EXIT]]
+; CHECK: if.exit:
+; CHECK-NEXT: [[RET:%.*]] = phi float [ [[FADD]], [[IF_THEN]] ], [ [[ARG]], [[ENTRY:%.*]] ]
+; CHECK-NEXT: ret float [[RET]]
+;
+entry:
+ %cond = tail call i1 @llvm.is.fpclass.f32(float %arg, i32 144)
+ br i1 %cond, label %if.then, label %if.exit
+
+if.then:
+ %fadd = fadd float %arg, 1.0
+ br label %if.exit
+
+if.exit:
+ %ret = phi ninf float [ %fadd, %if.then ], [ %arg, %entry ]
+ %ret.fr = freeze float %ret
+ ret float %ret.fr
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
IsWellDefined = false; | ||
break; | ||
if (!::canCreateUndefOrPoison(Opr, Kind, | ||
/*ConsiderFlagsAndMetadata=*/true)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd prefer just checking ->hasPoisonGeneratingFlags()
in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I didn't notice that you pulled out the condition from the general Operator code below, and it's not phi specific. With that in mind, I like your original code more. Sorry about that.
…#161530) ninf/nnan in the phi node may produce poison values. They should be considered in `isGuaranteedNotToBeUndefOrPoison`. Closes llvm#161524.
ninf/nnan in the phi node may produce poison values. They should be considered in
isGuaranteedNotToBeUndefOrPoison
.Closes #161524.