Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
[BDCE] Don't check demanded bits on unsized types
Browse files Browse the repository at this point in the history
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311014 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Hal Finkel committed Aug 16, 2017
1 parent c79eba5 commit a62eb7b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 2 deletions.
15 changes: 13 additions & 2 deletions lib/Transforms/Scalar/BDCE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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);
}
}
Expand Down
18 changes: 18 additions & 0 deletions test/Transforms/BDCE/dead-void-ro.ll
Original file line number Diff line number Diff line change
@@ -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 }

0 comments on commit a62eb7b

Please sign in to comment.