@@ -767,12 +767,23 @@ GlobOptBlockData::MergeValueMaps(
767
767
768
768
if (iter2.IsValid () && bucket.value ->m_id == iter2.Data ().value ->m_id )
769
769
{
770
+ // Syms that are assigned to within the loop must have unique
771
+ // value numbers in the loop header after merging; a single
772
+ // prepass is not adequate to determine that sym values are
773
+ // equivalent through all possible loop paths.
774
+ bool forceUniqueValue =
775
+ isLoopBackEdge &&
776
+ !this ->globOpt ->IsLoopPrePass () &&
777
+ loop &&
778
+ loop->symsAssignedToInLoop ->Test (bucket.value ->m_id );
779
+
770
780
newValue =
771
781
this ->MergeValues (
772
782
bucket.element ,
773
783
iter2.Data ().element ,
774
784
iter2.Data ().value ,
775
785
isLoopBackEdge,
786
+ forceUniqueValue,
776
787
symsRequiringCompensation,
777
788
symsCreatedForMerge);
778
789
}
@@ -847,6 +858,7 @@ GlobOptBlockData::MergeValues(
847
858
Value *fromDataValue,
848
859
Sym *fromDataSym,
849
860
bool isLoopBackEdge,
861
+ bool forceUniqueValue,
850
862
BVSparse<JitArenaAllocator> *const symsRequiringCompensation,
851
863
BVSparse<JitArenaAllocator> *const symsCreatedForMerge)
852
864
{
@@ -879,22 +891,30 @@ GlobOptBlockData::MergeValues(
879
891
return toDataValue;
880
892
}
881
893
882
- // There may be other syms in toData that haven't been merged yet, referring to the current toData value for this sym. If
883
- // the merge produced a new value info, don't corrupt the value info for the other sym by changing the same value. Instead,
884
- // create one value per source value number pair per merge and reuse that for new value infos.
885
- Value *newValue = this ->globOpt ->valuesCreatedForMerge ->Lookup (sourceValueNumberPair, nullptr );
886
- if (newValue)
894
+ Value *newValue = nullptr ;
895
+ if (forceUniqueValue)
887
896
{
888
- Assert (sameValueNumber == (newValue->GetValueNumber () == toDataValue->GetValueNumber ()));
889
-
890
- // This is an exception where Value::SetValueInfo is called directly instead of GlobOpt::ChangeValueInfo, because we're
891
- // actually generating new value info through merges.
892
- newValue->SetValueInfo (newValueInfo);
897
+ newValue = this ->globOpt ->NewValue (newValueInfo);
893
898
}
894
899
else
895
900
{
896
- newValue = this ->globOpt ->NewValue (sameValueNumber ? sourceValueNumberPair.First () : this ->globOpt ->NewValueNumber (), newValueInfo);
897
- this ->globOpt ->valuesCreatedForMerge ->Add (sourceValueNumberPair, newValue);
901
+ // There may be other syms in toData that haven't been merged yet, referring to the current toData value for this sym. If
902
+ // the merge produced a new value info, don't corrupt the value info for the other sym by changing the same value. Instead,
903
+ // create one value per source value number pair per merge and reuse that for new value infos.
904
+ newValue = this ->globOpt ->valuesCreatedForMerge ->Lookup (sourceValueNumberPair, nullptr );
905
+ if (newValue)
906
+ {
907
+ Assert (sameValueNumber == (newValue->GetValueNumber () == toDataValue->GetValueNumber ()));
908
+
909
+ // This is an exception where Value::SetValueInfo is called directly instead of GlobOpt::ChangeValueInfo, because we're
910
+ // actually generating new value info through merges.
911
+ newValue->SetValueInfo (newValueInfo);
912
+ }
913
+ else
914
+ {
915
+ newValue = this ->globOpt ->NewValue (sameValueNumber ? sourceValueNumberPair.First () : this ->globOpt ->NewValueNumber (), newValueInfo);
916
+ this ->globOpt ->valuesCreatedForMerge ->Add (sourceValueNumberPair, newValue);
917
+ }
898
918
}
899
919
900
920
// Set symStore if same on both paths.
0 commit comments