Skip to content

Commit

Permalink
Fix a bug which caused by one node op_uses itself when add_block
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhangZhuoSJTU authored and Anton Kochkov committed Aug 23, 2017
1 parent 6673e67 commit 87bfab3
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 1 deletion.
17 changes: 17 additions & 0 deletions scripts/bug-digger.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

# Script used to trigger a potential bug
# Usage: ./bug-digger.sh "YOURCOMMAND"
# Example: ./bug-digger.sh "cargo test analysis::valueset::fixcall::test::fix_test -- --nocapture"

num=0
echo "Begin"
while [ $? -eq 0 ]
do
echo $num
num=`expr $num + 1`
$1 > /tmp/out
done

# Output err
cat /tmp/out
1 change: 1 addition & 0 deletions src/analysis/cse/ssasort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ impl<'a, I, T> Sorter<'a, I, T>
// Operands' length must be 2, for only commutative opcode
// could get in this function, while commutative opcodes
// always have two operands.
assert_eq!(operands.len(), 2);
if self.compare(operands[0], operands[1]) == Ordering::Less {
self.ssa.disconnect(&idx, &operands[0]);
self.ssa.disconnect(&idx, &operands[1]);
Expand Down
17 changes: 16 additions & 1 deletion src/middle/phiplacement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,12 @@ impl<'a, T: SSAMod<BBInfo=MAddress> + SSAExtra + 'a> PhiPlacer<'a, T> {
}
} else {
// Incomplete CFG
// Actually, the incomplete_phis should not have the variable key.
let val_ = self.add_phi(address, valtype);
let block_addr = self.addr_of(&block);
if let Some(hash) = self.incomplete_phis.get_mut(&block_addr) {
assert!(hash.get(&variable).is_none(), "Double phi nodes for a same variable in\
same block!");
match hash.get(&variable).cloned() {
Some(v) => v,
None => {
Expand Down Expand Up @@ -273,10 +276,22 @@ impl<'a, T: SSAMod<BBInfo=MAddress> + SSAExtra + 'a> PhiPlacer<'a, T> {
// - Connect the edge.
// The above two steps can easily be accomplished by doing a read_variable
// and adding an operand edge.
// BUG: Not all operands are the register residences.
// For example, OpWiden for 32-bit register. If we want to add a 32-bit register
// with a constant, our algorithm will add an Opwiden(64) node for the register,
// then add the OpWiden node with an Opconst. In this situation, OpWiden
// node isn't a residence for any register.
if !self.outputs.contains_key(&operand) {
continue;
}
self.ssa.disconnect(&ni, &operand);
let output_varid = self.outputs[&operand];
let mut at_ = at;
let replacement_phi = self.read_variable(&mut at_, output_varid);
// BUG: if current define is ni itself, this code may cause ni use itself
// as operand. So we have to do some check.
// A tricky way to solve the bug is to call read_variable_recursive, rather
// than read_variable, this will force the code generate a phi node.
let replacement_phi = self.read_variable_recursive(output_varid, &mut at_);
self.ssa.op_use(ni, i, replacement_phi);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/middle/ssa/ssastorage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,8 @@ impl SSAMod for SSAStorage {
if argument == NodeIndex::end() {
return;
}
// A node cannot use itself.
assert_ne!(node, argument);
self.insert_edge(node, argument, EdgeData::Data(index));
}

Expand Down

0 comments on commit 87bfab3

Please sign in to comment.