summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHal Finkel <hfinkel@anl.gov>2017-08-16 16:09:22 +0000
committerHal Finkel <hfinkel@anl.gov>2017-08-16 16:09:22 +0000
commit9e54b7093abda564ddd88bb0c8ee2c97be50082a (patch)
treed69a5e581161d877366d04008f59e52279b3e0c0
parent8c3edfef6b911f8e0e2d64169ffaea7077481f3f (diff)
downloadbcm5719-llvm-9e54b7093abda564ddd88bb0c8ee2c97be50082a.tar.gz
bcm5719-llvm-9e54b7093abda564ddd88bb0c8ee2c97be50082a.zip
[BDCE] Don't check demanded bits on unsized types
To clear assumptions that are potentially invalid after trivialization, we need to walk the use/def chain. Normally, the only way to reach an instruction with an unsized type is via an instruction that has side effects (or otherwise will demand its input bits). That would stop the walk. However, if we have a readnone function that returns an unsized type (e.g., void), we must avoid asking for the demanded bits of the function call's return value. A void-returning readnone function is always dead (and so we can stop walking the use/def chain here), but the check is necessary to avoid asserting. Fixes PR34211. llvm-svn: 311014
-rw-r--r--llvm/lib/Transforms/Scalar/BDCE.cpp15
-rw-r--r--llvm/test/Transforms/BDCE/dead-void-ro.ll18
2 files changed, 31 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/Scalar/BDCE.cpp b/llvm/lib/Transforms/Scalar/BDCE.cpp
index 2e5618686ec..9d7997be1eb 100644
--- a/llvm/lib/Transforms/Scalar/BDCE.cpp
+++ b/llvm/lib/Transforms/Scalar/BDCE.cpp
@@ -48,8 +48,18 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) {
// If all bits of a user are demanded, then we know that nothing below that
// in the def-use chain needs to be changed.
auto *J = dyn_cast<Instruction>(JU);
- if (J && !DB.getDemandedBits(J).isAllOnesValue())
+ if (J && J->getType()->isSized() &&
+ !DB.getDemandedBits(J).isAllOnesValue())
WorkList.push_back(J);
+
+ // Note that we need to check for unsized types above before asking for
+ // demanded bits. Normally, the only way to reach an instruction with an
+ // unsized type is via an instruction that has side effects (or otherwise
+ // will demand its input bits). However, if we have a readnone function
+ // that returns an unsized type (e.g., void), we must avoid asking for the
+ // demanded bits of the function call's return value. A void-returning
+ // readnone function is always dead (and so we can stop walking the use/def
+ // chain here), but the check is necessary to avoid asserting.
}
// DFS through subsequent users while tracking visits to avoid cycles.
@@ -70,7 +80,8 @@ static void clearAssumptionsOfUsers(Instruction *I, DemandedBits &DB) {
// If all bits of a user are demanded, then we know that nothing below
// that in the def-use chain needs to be changed.
auto *K = dyn_cast<Instruction>(KU);
- if (K && !Visited.count(K) && !DB.getDemandedBits(K).isAllOnesValue())
+ if (K && !Visited.count(K) && K->getType()->isSized() &&
+ !DB.getDemandedBits(K).isAllOnesValue())
WorkList.push_back(K);
}
}
diff --git a/llvm/test/Transforms/BDCE/dead-void-ro.ll b/llvm/test/Transforms/BDCE/dead-void-ro.ll
new file mode 100644
index 00000000000..36f09511503
--- /dev/null
+++ b/llvm/test/Transforms/BDCE/dead-void-ro.ll
@@ -0,0 +1,18 @@
+; RUN: opt -S -bdce < %s | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @PR34211(i16* %p) {
+; CHECK-LABEL: @PR34211
+ %not_demanded_but_not_dead = load volatile i16, i16* %p
+ call void @no_side_effects_so_dead(i16 %not_demanded_but_not_dead)
+ ret void
+
+; CHECK: %not_demanded_but_not_dead = load volatile i16, i16* %p
+; CHECK-NEXT: ret void
+}
+
+declare void @no_side_effects_so_dead(i16) #0
+
+attributes #0 = { nounwind readnone }
+
OpenPOWER on IntegriCloud