diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-11-14 08:50:16 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-11-14 08:50:16 +0000 |
commit | 2770c141856eefda6a192622bf5fd5b06bef4963 (patch) | |
tree | 8d91e1c1d623b3040323b1817f26ff53348e6dac /test | |
parent | dcce244dd85ec410c2e0b8ac2b23320df3e3ece9 (diff) | |
download | external_llvm-2770c141856eefda6a192622bf5fd5b06bef4963.zip external_llvm-2770c141856eefda6a192622bf5fd5b06bef4963.tar.gz external_llvm-2770c141856eefda6a192622bf5fd5b06bef4963.tar.bz2 |
Fix an overflow bug in MachineBranchProbabilityInfo. This pass relied on
the sum of the edge weights not overflowing uint32, and crashed when
they did. This is generally safe as BranchProbabilityInfo tries to
provide this guarantee. However, the CFG can get modified during codegen
in a way that grows the *sum* of the edge weights. This doesn't seem
unreasonable (imagine just adding more blocks all with the default
weight of 16), but it is hard to come up with a case that actually
triggers 32-bit overflow. Fortuately, the single-source GCC build is
good at this. The solution isn't very pretty, but its no worse than the
previous code. We're already summing all of the edge weights on each
query, we can sum them, check for an overflow, compute a scale, and sum
them again.
I've included a *greatly* reduced test case out of the GCC source that
triggers it. It's a pretty lame test, as it clearly is just barely
triggering the overflow. I'd like to have something that is much more
definitive, but I don't understand the fundamental pattern that triggers
an explosion in the edge weight sums.
The buggy code is duplicated within this file. I'll colapse them into
a single implementation in a subsequent commit.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144526 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGen/X86/block-placement.ll | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/test/CodeGen/X86/block-placement.ll b/test/CodeGen/X86/block-placement.ll index fed27c6..e41d52c 100644 --- a/test/CodeGen/X86/block-placement.ll +++ b/test/CodeGen/X86/block-placement.ll @@ -271,3 +271,54 @@ loop.body5: %ptr2 = load i32** undef, align 4 br label %loop.body3 } + +define i32 @problematic_switch() { +; This function's CFG caused overlow in the machine branch probability +; calculation, triggering asserts. Make sure we don't crash on it. +; CHECK: problematic_switch + +entry: + switch i32 undef, label %exit [ + i32 879, label %bogus + i32 877, label %step + i32 876, label %step + i32 875, label %step + i32 874, label %step + i32 873, label %step + i32 872, label %step + i32 868, label %step + i32 867, label %step + i32 866, label %step + i32 861, label %step + i32 860, label %step + i32 856, label %step + i32 855, label %step + i32 854, label %step + i32 831, label %step + i32 830, label %step + i32 829, label %step + i32 828, label %step + i32 815, label %step + i32 814, label %step + i32 811, label %step + i32 806, label %step + i32 805, label %step + i32 804, label %step + i32 803, label %step + i32 802, label %step + i32 801, label %step + i32 800, label %step + i32 799, label %step + i32 798, label %step + i32 797, label %step + i32 796, label %step + i32 795, label %step + ] +bogus: + unreachable +step: + br label %exit +exit: + %merge = phi i32 [ 3, %step ], [ 6, %entry ] + ret i32 %merge +} |