From 7aa084c9fd5f080f7b45a50e6decc778b5951133 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 3 Sep 2026 18:55:10 +0100 Subject: [PATCH 1/2] C++: Fix join in AliasedSSA. Before (on an internal Microsoft repo): Evaluated relational algebra for predicate AliasedSSA::AllocationMemoryLocation.getVirtualVariable/0#dispred#8debd926@f62ba08v with tuple counts: 5606472 ~0% {2} r1 = AliasedSSA::AllocationMemoryLocation#57439a9b_10#join_rhs AND NOT `AliasAnalysis::allocationEscapes/1#93dc9772`(FIRST 1) 5534569 ~0% {2} r2 = r1 AND NOT `project#AliasedSSA::getGroupedMemoryLocation/3#14ef79fc#ffbf`(FIRST 1) 10613026097 ~0% {2} | JOIN WITH AliasedSSA::AllocationMemoryLocation#57439a9b_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 5534569 ~6% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 759836 ~0% {2} r3 = JOIN AliasedSSA::AllocationMemoryLocation#57439a9b_10#join_rhs WITH `AliasAnalysis::allocationEscapes/1#93dc9772` ON FIRST 1 OUTPUT Lhs.0, Lhs.1 759832 ~6% {3} | JOIN WITH `AliasConfiguration::Allocation.getEnclosingIRFunction/0#dispred#3254a7ee` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1 759832 ~0% {3} | REWRITE WITH Out.1 := false 759832 ~1% {2} | JOIN WITH num#AliasedSSA::TAllAliasedMemory#4bb632db ON FIRST 2 OUTPUT Rhs.2, Lhs.2 759832 ~1% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 5606472 ~0% {4} r4 = SCAN r1 OUTPUT In.0, _, _, In.1 5606472 ~0% {4} | REWRITE WITH Out.1 := false, Out.2 := false 71903 ~5% {2} | JOIN WITH `AliasedSSA::getGroupedMemoryLocation/3#14ef79fc#ffbf` ON FIRST 3 OUTPUT Rhs.3, Lhs.3 71903 ~3% {2} | JOIN WITH `AliasedSSA::GroupedMemoryLocation.getVirtualVariable/0#dispred#143f2d1b` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 71903 ~2% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 6366304 ~5% {2} r5 = r2 UNION r3 UNION r4 return r5 After: [2026-09-03 14:39:34] Evaluated non-recursive predicate AliasedSSA::getAllocationMemoryLocation/1#171552fa@42e30agr in 15ms (size: 505315). Evaluated relational algebra for predicate AliasedSSA::getAllocationMemoryLocation/1#171552fa@42e30agr with tuple counts: 505315 ~2% {2} r1 = JOIN AliasedSSA::VirtualVariable#5712df39 WITH `AliasedSSA::MemoryLocation0.getAnAllocation/0#dispred#f0047858` ON FIRST 1 OUTPUT Rhs.1, Lhs.0 return r1 [2026-09-03 14:39:39] Evaluated non-recursive predicate AliasedSSA::AllocationMemoryLocation.getVirtualVariable/0#dispred#8debd926@21855asb in 1811ms (size: 6366304). Evaluated relational algebra for predicate AliasedSSA::AllocationMemoryLocation.getVirtualVariable/0#dispred#8debd926@21855asb with tuple counts: 5606472 ~0% {2} r1 = AliasedSSA::AllocationMemoryLocation#57439a9b_10#join_rhs AND NOT `AliasAnalysis::allocationEscapes/1#93dc9772`(FIRST 1) 5534569 ~0% {2} r2 = r1 AND NOT `project#AliasedSSA::getGroupedMemoryLocation/3#14ef79fc#ffbf`(FIRST 1) 5534569 ~1% {2} | JOIN WITH `AliasedSSA::getAllocationMemoryLocation/1#171552fa` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 5534569 ~6% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 759836 ~0% {2} r3 = JOIN AliasedSSA::AllocationMemoryLocation#57439a9b_10#join_rhs WITH `AliasAnalysis::allocationEscapes/1#93dc9772` ON FIRST 1 OUTPUT Lhs.0, Lhs.1 759832 ~6% {3} | JOIN WITH `AliasConfiguration::Allocation.getEnclosingIRFunction/0#dispred#3254a7ee` ON FIRST 1 OUTPUT Rhs.1, _, Lhs.1 759832 ~0% {3} | REWRITE WITH Out.1 := false 759832 ~1% {2} | JOIN WITH num#AliasedSSA::TAllAliasedMemory#4bb632db ON FIRST 2 OUTPUT Rhs.2, Lhs.2 759832 ~1% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 5606472 ~0% {4} r4 = SCAN r1 OUTPUT In.0, _, _, In.1 5606472 ~0% {4} | REWRITE WITH Out.1 := false, Out.2 := false 71903 ~5% {2} | JOIN WITH `AliasedSSA::getGroupedMemoryLocation/3#14ef79fc#ffbf` ON FIRST 3 OUTPUT Rhs.3, Lhs.3 71903 ~3% {2} | JOIN WITH `AliasedSSA::GroupedMemoryLocation.getVirtualVariable/0#dispred#143f2d1b` ON FIRST 1 OUTPUT Rhs.1, Lhs.1 71903 ~2% {2} | JOIN WITH AliasedSSA::VirtualVariable#5712df39 ON FIRST 1 OUTPUT Lhs.1, Lhs.0 6366304 ~5% {2} r5 = r2 UNION r3 UNION r4 return r5 --- .../ir/implementation/aliased_ssa/internal/AliasedSSA.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll index 2ace50221313..59ee08973e1a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll @@ -295,6 +295,11 @@ abstract class MemoryLocation0 extends TMemoryLocation { */ abstract class VirtualVariable extends MemoryLocation0 { } +pragma[nomagic] +private VirtualVariable getAllocationMemoryLocation(Allocation alloc) { + result.getAnAllocation() = alloc +} + abstract class AllocationMemoryLocation extends MemoryLocation0 { Allocation var; boolean isMayAccess; @@ -313,7 +318,7 @@ abstract class AllocationMemoryLocation extends MemoryLocation0 { result = getGroupedMemoryLocation(var, false, false).getVirtualVariable() or not exists(getGroupedMemoryLocation(var, false, false)) and - result.(AllocationMemoryLocation).getAnAllocation() = var + result = getAllocationMemoryLocation(var) ) } From c99bff955ecdd663e298955a4df8128c4861af79 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 3 Sep 2026 18:57:10 +0100 Subject: [PATCH 2/2] C++: Fix join in IR construction. Before (on an internal Microsoft repo): [2026-08-28 14:36:46] Evaluated non-recursive predicate TranslatedElement::TranslatedElement.getInstructionSuccessorInternal/2#dispred#a6e054ca@2248725r in 470505ms (size: 136995987). Evaluated relational algebra for predicate TranslatedElement::TranslatedElement.getInstructionSuccessorInternal/2#dispred#a6e054ca@2248725r with tuple counts: 437 ~0% {2} r158 = JOIN EdgeKind::EdgeKindImpl#8ed21aeb WITH num#InstructionTag::CallTargetTag#8c4ab419 CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0 437 ~0% {3} | JOIN WITH num#InstructionTag::CallTag#a77d4021 CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Lhs.1 1070556919 ~0% {4} | JOIN WITH `TranslatedElement::TranslatedElement.getInstruction/1#dispred#f6df9482_102#join_rhs` ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Rhs.2 316388 ~1% {4} | JOIN WITH TranslatedInitialization::TranslatedDefaultFieldInitialization#d9c761ed ON FIRST 1 OUTPUT Lhs.0, Lhs.2, Lhs.1, Lhs.3 After: [2026-09-03 13:56:28] Evaluated non-recursive predicate TranslatedInitialization::getCallInstruction/1#c88d849b@3e960544 in 40ms (size: 724). Evaluated relational algebra for predicate TranslatedInitialization::getCallInstruction/1#c88d849b@3e960544 with tuple counts: 724 ~3% {2} r1 = JOIN `_TranslatedElement::TranslatedElement.getInstruction/1#dispred#f6df9482_102#join_rhs_num#Instruction__#shared#1` WITH TranslatedInitialization::TranslatedDefaultFieldInitialization#d9c761ed ON FIRST 1 OUTPUT Lhs.0, Lhs.1 return r1 437 ~0% {2} r5 = JOIN EdgeKind::EdgeKindImpl#8ed21aeb WITH num#InstructionTag::CallTargetTag#8c4ab419 CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.0 316388 ~1% {4} | JOIN WITH `TranslatedInitialization::getCallInstruction/1#c88d849b` CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.1, Lhs.0, Rhs.1 --- .../raw/internal/TranslatedInitialization.qll | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll index 10c033131225..c24cb98d2bd9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -618,6 +618,11 @@ class TranslatedExplicitFieldInitialization extends TranslatedNonDefaultFieldIni override int getPosition() { result = position } } +pragma[nomagic] +private Instruction getCallInstruction(TranslatedDefaultFieldInitialization tdfi) { + result = tdfi.getInstruction(CallTag()) +} + /** * The IR translation of the initialization of a field from an element of an initializer * list where default initialization is used. @@ -642,7 +647,7 @@ class TranslatedDefaultFieldInitialization extends TranslatedFieldInitialization override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { tag = CallTargetTag() and - result = this.getInstruction(CallTag()) + result = getCallInstruction(this) or tag = CallTag() and result = this.getSideEffects().getFirstInstruction(kind)