@@ -2071,28 +2071,38 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN)
20712071 assert (func != VNF_MemOpaque);
20722072 assert (arg0VN == VNNormalValue (arg0VN)); // Arguments don't carry exceptions.
20732073
2074- // Try to perform constant-folding.
2075- if (VNEvalCanFoldUnaryFunc (typ, func, arg0VN))
2076- {
2077- return EvalFuncForConstantArgs (typ, func, arg0VN);
2078- }
2079-
2080- ValueNum resultVN;
2074+ ValueNum resultVN = NoVN;
20812075
20822076 // Have we already assigned a ValueNum for 'func'('arg0VN') ?
2077+ //
20832078 VNDefFuncApp<1 > fstruct (func, arg0VN);
2084- if (! GetVNFunc1Map ()->Lookup (fstruct, &resultVN))
2079+ if (GetVNFunc1Map ()->Lookup (fstruct, &resultVN))
20852080 {
2081+ assert (resultVN != NoVN);
2082+ }
2083+ else
2084+ {
2085+ // Try to perform constant-folding.
2086+ //
2087+ if (VNEvalCanFoldUnaryFunc (typ, func, arg0VN))
2088+ {
2089+ resultVN = EvalFuncForConstantArgs (typ, func, arg0VN);
2090+ }
2091+
20862092 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN')
20872093 //
2088- Chunk* const c = GetAllocChunk (typ, CEA_Func1);
2089- unsigned const offsetWithinChunk = c->AllocVN ();
2090- VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 1 );
2091- fapp->m_func = func;
2092- fapp->m_args [0 ] = arg0VN;
2093- resultVN = c->m_baseVN + offsetWithinChunk;
2094+ if (resultVN == NoVN)
2095+ {
2096+ Chunk* const c = GetAllocChunk (typ, CEA_Func1);
2097+ unsigned const offsetWithinChunk = c->AllocVN ();
2098+ VNDefFuncAppFlexible* fapp = c->PointerToFuncApp (offsetWithinChunk, 1 );
2099+ fapp->m_func = func;
2100+ fapp->m_args [0 ] = arg0VN;
2101+ resultVN = c->m_baseVN + offsetWithinChunk;
2102+ }
20942103
20952104 // Record 'resultVN' in the Func1Map
2105+ //
20962106 GetVNFunc1Map ()->Set (fstruct, resultVN);
20972107 }
20982108 return resultVN;
@@ -2123,16 +2133,7 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
21232133 assert ((VNFuncArity (func) == 0 ) || (VNFuncArity (func) == 2 ));
21242134 assert (func != VNF_MapSelect); // Precondition: use the special function VNForMapSelect defined for that.
21252135
2126- ValueNum resultVN;
2127-
2128- // When both operands are constants we can usually perform constant-folding,
2129- // except if the expression will always throw an exception (constant VN-based
2130- // propagation depends on that).
2131- //
2132- if (VNEvalCanFoldBinaryFunc (typ, func, arg0VN, arg1VN) && VNEvalShouldFold (typ, func, arg0VN, arg1VN))
2133- {
2134- return EvalFuncForConstantArgs (typ, func, arg0VN, arg1VN);
2135- }
2136+ ValueNum resultVN = NoVN;
21362137
21372138 // We canonicalize commutative operations.
21382139 // (Perhaps should eventually handle associative/commutative [AC] ops -- but that gets complicated...)
@@ -2148,7 +2149,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
21482149 // Have we already assigned a ValueNum for 'func'('arg0VN','arg1VN') ?
21492150 //
21502151 VNDefFuncApp<2 > fstruct (func, arg0VN, arg1VN);
2151- if (!GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2152+ if (GetVNFunc2Map ()->Lookup (fstruct, &resultVN))
2153+ {
2154+ assert (resultVN != NoVN);
2155+ }
2156+ else
21522157 {
21532158 if (func == VNF_CastClass)
21542159 {
@@ -2159,10 +2164,27 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
21592164 }
21602165 else
21612166 {
2162- resultVN = EvalUsingMathIdentity (typ, func, arg0VN, arg1VN);
2167+ // When both operands are constants we can usually perform constant-folding,
2168+ // except if the expression will always throw an exception (constant VN-based
2169+ // propagation depends on that).
2170+ //
2171+ bool folded = false ;
2172+ if (VNEvalCanFoldBinaryFunc (typ, func, arg0VN, arg1VN) && VNEvalShouldFold (typ, func, arg0VN, arg1VN))
2173+ {
2174+ resultVN = EvalFuncForConstantArgs (typ, func, arg0VN, arg1VN);
2175+ }
2176+
2177+ if (resultVN != NoVN)
2178+ {
2179+ folded = true ;
2180+ }
2181+ else
2182+ {
2183+ resultVN = EvalUsingMathIdentity (typ, func, arg0VN, arg1VN);
2184+ }
21632185
21642186 // Do we have a valid resultVN?
2165- if ((resultVN == NoVN) || (genActualType (TypeOfVN (resultVN)) != genActualType (typ)))
2187+ if ((resultVN == NoVN) || (!folded && ( genActualType (TypeOfVN (resultVN)) != genActualType (typ) )))
21662188 {
21672189 // Otherwise, Allocate a new ValueNum for 'func'('arg0VN','arg1VN')
21682190 //
@@ -2173,10 +2195,11 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN, V
21732195 fapp->m_args [0 ] = arg0VN;
21742196 fapp->m_args [1 ] = arg1VN;
21752197 resultVN = c->m_baseVN + offsetWithinChunk;
2176- // Record 'resultVN' in the Func2Map
2177- GetVNFunc2Map ()->Set (fstruct, resultVN);
21782198 }
21792199 }
2200+
2201+ // Record 'resultVN' in the Func2Map
2202+ GetVNFunc2Map ()->Set (fstruct, resultVN);
21802203 }
21812204 return resultVN;
21822205}
@@ -9389,7 +9412,16 @@ ValueNumPair ValueNumStore::VNPairForCast(ValueNumPair srcVNPair,
93899412 ValueNum srcLibVN = srcVNPair.GetLiberal ();
93909413 ValueNum srcConVN = srcVNPair.GetConservative ();
93919414 ValueNum castLibVN = VNForCast (srcLibVN, castToType, castFromType, srcIsUnsigned, hasOverflowCheck);
9392- ValueNum castConVN = VNForCast (srcConVN, castToType, castFromType, srcIsUnsigned, hasOverflowCheck);
9415+ ValueNum castConVN;
9416+
9417+ if (srcVNPair.BothEqual ())
9418+ {
9419+ castConVN = castLibVN;
9420+ }
9421+ else
9422+ {
9423+ castConVN = VNForCast (srcConVN, castToType, castFromType, srcIsUnsigned, hasOverflowCheck);
9424+ }
93939425
93949426 return {castLibVN, castConVN};
93959427}
@@ -9476,7 +9508,16 @@ ValueNumPair ValueNumStore::VNPairForBitCast(ValueNumPair srcVNPair, var_types c
94769508 ValueNum srcConVN = srcVNPair.GetConservative ();
94779509
94789510 ValueNum bitCastLibVN = VNForBitCast (srcLibVN, castToType);
9479- ValueNum bitCastConVN = VNForBitCast (srcConVN, castToType);
9511+ ValueNum bitCastConVN;
9512+
9513+ if (srcVNPair.BothEqual ())
9514+ {
9515+ bitCastConVN = bitCastLibVN;
9516+ }
9517+ else
9518+ {
9519+ bitCastConVN = VNForBitCast (srcConVN, castToType);
9520+ }
94809521
94819522 return ValueNumPair (bitCastLibVN, bitCastConVN);
94829523}
0 commit comments