mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C++ IR: Don't propagate GVN through non-exact Copy
The `ValueNumbering` library is supposed to propagate value numberings through a `CopyInstruction` only when it's _congruent_, meaning it must have exact overlap with its source. A `CopyInstruction` can be a `LoadInstruction`, a `StoreInstruction`, or a `CopyValueInstruction`. The latter is also a `UnaryInstruction`, and the value numbering rule for `UnaryInstruction` applied to it as well. This meant that value numbering would propagate even through a non-congruent `CopyValueInstruction`. That's semantically wrong but probably only an issue in very rare circumstances, and it should get corrected when we change the definition of `getUnary` to require congruence. What's worse is the performance implications. It meant that the value numbering IPA witness could take two different paths through every `CopyValueInstruction`. If multiple `CopyValueInstruction`s were chained, this would lead to an exponential number of variable numbers for the same `Instruction`, and we would run out of time and space while performing value numbering. This fixes the performance of `ValueNumbering.qll` on https://github.com/asterisk/asterisk, although this project might also require a separate change for fixing an infinite loop in the IR constant analysis.
This commit is contained in:
@@ -124,7 +124,7 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof StringConstantInstruction or
|
||||
instr instanceof FieldAddressInstruction or
|
||||
instr instanceof BinaryInstruction or
|
||||
instr instanceof UnaryInstruction or
|
||||
(instr instanceof UnaryInstruction and not instr instanceof CopyInstruction) or
|
||||
instr instanceof PointerArithmeticInstruction or
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
@@ -191,6 +191,7 @@ private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Op
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
(not instr instanceof CopyInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
valueNumber(instr.getUnary()) = operand
|
||||
|
||||
@@ -124,7 +124,7 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof StringConstantInstruction or
|
||||
instr instanceof FieldAddressInstruction or
|
||||
instr instanceof BinaryInstruction or
|
||||
instr instanceof UnaryInstruction or
|
||||
(instr instanceof UnaryInstruction and not instr instanceof CopyInstruction) or
|
||||
instr instanceof PointerArithmeticInstruction or
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
@@ -191,6 +191,7 @@ private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Op
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
(not instr instanceof CopyInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
valueNumber(instr.getUnary()) = operand
|
||||
|
||||
@@ -124,7 +124,7 @@ private predicate numberableInstruction(Instruction instr) {
|
||||
instr instanceof StringConstantInstruction or
|
||||
instr instanceof FieldAddressInstruction or
|
||||
instr instanceof BinaryInstruction or
|
||||
instr instanceof UnaryInstruction or
|
||||
(instr instanceof UnaryInstruction and not instr instanceof CopyInstruction) or
|
||||
instr instanceof PointerArithmeticInstruction or
|
||||
instr instanceof CongruentCopyInstruction
|
||||
}
|
||||
@@ -191,6 +191,7 @@ private predicate unaryValueNumber(UnaryInstruction instr, IRFunction irFunc, Op
|
||||
Type type, ValueNumber operand) {
|
||||
instr.getEnclosingIRFunction() = irFunc and
|
||||
(not instr instanceof InheritanceConversionInstruction) and
|
||||
(not instr instanceof CopyInstruction) and
|
||||
instr.getOpcode() = opcode and
|
||||
instr.getResultType() = type and
|
||||
valueNumber(instr.getUnary()) = operand
|
||||
|
||||
Reference in New Issue
Block a user