@@ -52,6 +52,11 @@ newtype TValueNumber =
5252 ) {
5353 inheritanceConversionValueNumber ( _, irFunc , opcode , baseClass , derivedClass , operand )
5454 } or
55+ TCongruentCopyInstructionTotal (
56+ IRFunction irFunc , IRType type , ValueNumber memOperand , ValueNumber operand
57+ ) {
58+ congruentCopyInstructionTotalValueNumber ( _, irFunc , type , memOperand , operand )
59+ } or
5560 TUniqueValueNumber ( IRFunction irFunc , Instruction instr ) { uniqueValueNumber ( instr , irFunc ) }
5661
5762/**
@@ -101,12 +106,18 @@ class ValueNumber extends TValueNumber {
101106 * The use of `p.x` on line 3 is linked to the definition of `p` on line 1 as well, but is not
102107 * congruent to that definition because `p.x` accesses only a subset of the memory defined by `p`.
103108 */
104- private class CongruentCopyInstruction extends CopyInstruction {
105- CongruentCopyInstruction ( ) {
109+ class CongruentCopyInstructionExact extends CopyInstruction {
110+ CongruentCopyInstructionExact ( ) {
106111 this .getSourceValueOperand ( ) .getDefinitionOverlap ( ) instanceof MustExactlyOverlap
107112 }
108113}
109114
115+ class CongruentCopyInstructionTotal extends CopyInstruction {
116+ CongruentCopyInstructionTotal ( ) {
117+ this .getSourceValueOperand ( ) .getDefinitionOverlap ( ) instanceof MustTotallyOverlap
118+ }
119+ }
120+
110121/**
111122 * Holds if this library knows how to assign a value number to the specified instruction, other than
112123 * a `unique` value number that is never shared by multiple instructions.
@@ -130,7 +141,9 @@ private predicate numberableInstruction(Instruction instr) {
130141 or
131142 instr instanceof PointerArithmeticInstruction
132143 or
133- instr instanceof CongruentCopyInstruction
144+ instr instanceof CongruentCopyInstructionExact
145+ or
146+ instr instanceof CongruentCopyInstructionTotal
134147}
135148
136149private predicate variableAddressValueNumber (
@@ -205,6 +218,7 @@ private predicate unaryValueNumber(
205218 instr .getEnclosingIRFunction ( ) = irFunc and
206219 not instr instanceof InheritanceConversionInstruction and
207220 not instr instanceof CopyInstruction and
221+ not instr instanceof FieldAddressInstruction and
208222 instr .getOpcode ( ) = opcode and
209223 instr .getResultIRType ( ) = type and
210224 valueNumber ( instr .getUnary ( ) ) = operand
@@ -221,6 +235,16 @@ private predicate inheritanceConversionValueNumber(
221235 valueNumber ( instr .getUnary ( ) ) = operand
222236}
223237
238+ private predicate congruentCopyInstructionTotalValueNumber (
239+ CongruentCopyInstructionTotal instr , IRFunction irFunc , IRType type , ValueNumber memOperand ,
240+ ValueNumber operand
241+ ) {
242+ instr .getEnclosingIRFunction ( ) = irFunc and
243+ instr .getResultIRType ( ) = type and
244+ valueNumber ( instr .getAnOperand ( ) .( MemoryOperand ) .getAnyDef ( ) ) = memOperand and
245+ valueNumberOfOperand ( instr .getAnOperand ( ) .( AddressOperand ) ) = operand
246+ }
247+
224248/**
225249 * Holds if `instr` should be assigned a unique value number because this library does not know how
226250 * to determine if two instances of that instruction are equivalent.
@@ -313,8 +337,13 @@ private ValueNumber nonUniqueValueNumber(Instruction instr) {
313337 TPointerArithmeticValueNumber ( irFunc , opcode , type , elementSize , leftOperand , rightOperand )
314338 )
315339 or
340+ exists ( IRType type , ValueNumber memOperand , ValueNumber operand |
341+ congruentCopyInstructionTotalValueNumber ( instr , irFunc , type , memOperand , operand ) and
342+ result = TCongruentCopyInstructionTotal ( irFunc , type , memOperand , operand )
343+ )
344+ or
316345 // The value number of a copy is just the value number of its source value.
317- result = valueNumber ( instr .( CongruentCopyInstruction ) .getSourceValue ( ) )
346+ result = valueNumber ( instr .( CongruentCopyInstructionExact ) .getSourceValue ( ) )
318347 )
319348 )
320349}
0 commit comments