@@ -331,6 +331,37 @@ TypeTree getConstantAnalysis(Constant *Val, TypeAnalyzer &TA) {
331
331
// ConstantExprs are handled by considering the
332
332
// equivalent instruction
333
333
if (auto CE = dyn_cast<ConstantExpr>(Val)) {
334
+ if (CE->isCast ()) {
335
+ if (CE->getType ()->isPointerTy () && isa<ConstantInt>(CE->getOperand (0 )))
336
+ return TypeTree (BaseType::Anything).Only (-1 );
337
+ return getConstantAnalysis (CE->getOperand (0 ), TA);
338
+ }
339
+ if (CE->isGEPWithNoNotionalOverIndexing ()) {
340
+ auto gepData0 = getConstantAnalysis (CE->getOperand (0 ), TA).Data0 ();
341
+
342
+ auto g2 = cast<GetElementPtrInst>(CE->getAsInstruction ());
343
+ #if LLVM_VERSION_MAJOR > 6
344
+ APInt ai (DL.getIndexSizeInBits (g2->getPointerAddressSpace ()), 0 );
345
+ #else
346
+ APInt ai (DL.getPointerSize (g2->getPointerAddressSpace ()) * 8 , 0 );
347
+ #endif
348
+ g2->accumulateConstantOffset (DL, ai);
349
+ // Using destructor rather than eraseFromParent
350
+ // as g2 has no parent
351
+ delete g2;
352
+
353
+ int off = (int )ai.getLimitedValue ();
354
+
355
+ // TODO also allow negative offsets
356
+ if (off < 0 )
357
+ return TypeTree (BaseType::Pointer).Only (-1 );
358
+
359
+ TypeTree result =
360
+ gepData0.ShiftIndices (DL, /* init offset*/ off, /* max size*/ -1 ,
361
+ /* new offset*/ 0 );
362
+ result.insert ({}, BaseType::Pointer);
363
+ return result.Only (-1 );
364
+ }
334
365
TypeTree Result;
335
366
336
367
auto I = CE->getAsInstruction ();
@@ -389,6 +420,8 @@ TypeTree TypeAnalyzer::getAnalysis(Value *Val) {
389
420
if (auto found = findInMap (analysis, Val)) {
390
421
result |= *found;
391
422
*found = result;
423
+ } else {
424
+ analysis[Val] = result;
392
425
}
393
426
return result;
394
427
}
@@ -481,7 +514,10 @@ void TypeAnalyzer::updateAnalysis(Value *Val, TypeTree Data, Value *Origin) {
481
514
482
515
// Attempt to update the underlying analysis
483
516
bool LegalOr = true ;
484
- auto prev = analysis[Val];
517
+ if (analysis.find (Val) == analysis.end () && isa<Constant>(Val))
518
+ analysis[Val] = getConstantAnalysis (cast<Constant>(Val), *this );
519
+
520
+ TypeTree prev = analysis[Val];
485
521
bool Changed =
486
522
analysis[Val].checkedOrIn (Data, /* PointerIntSame*/ false , LegalOr);
487
523
@@ -906,6 +942,68 @@ void TypeAnalyzer::visitValue(Value &val) {
906
942
}
907
943
908
944
void TypeAnalyzer::visitConstantExpr (ConstantExpr &CE) {
945
+ if (CE.isCast ()) {
946
+ if (direction & DOWN)
947
+ updateAnalysis (&CE, getAnalysis (CE.getOperand (0 )), &CE);
948
+ if (direction & UP)
949
+ updateAnalysis (CE.getOperand (0 ), getAnalysis (&CE), &CE);
950
+ return ;
951
+ }
952
+ if (CE.isGEPWithNoNotionalOverIndexing ()) {
953
+
954
+ auto &DL = fntypeinfo.Function ->getParent ()->getDataLayout ();
955
+ auto g2 = cast<GetElementPtrInst>(CE.getAsInstruction ());
956
+ #if LLVM_VERSION_MAJOR > 6
957
+ APInt ai (DL.getIndexSizeInBits (g2->getPointerAddressSpace ()), 0 );
958
+ #else
959
+ APInt ai (DL.getPointerSize (g2->getPointerAddressSpace ()) * 8 , 0 );
960
+ #endif
961
+ g2->accumulateConstantOffset (DL, ai);
962
+ // Using destructor rather than eraseFromParent
963
+ // as g2 has no parent
964
+
965
+ int maxSize = -1 ;
966
+ if (cast<ConstantInt>(CE.getOperand (1 ))->getLimitedValue () == 0 ) {
967
+ maxSize = DL.getTypeAllocSizeInBits (
968
+ cast<PointerType>(g2->getType ())->getElementType ()) /
969
+ 8 ;
970
+ }
971
+
972
+ delete g2;
973
+
974
+ int off = (int )ai.getLimitedValue ();
975
+
976
+ // TODO also allow negative offsets
977
+ if (off < 0 ) {
978
+ if (direction & DOWN)
979
+ updateAnalysis (&CE, TypeTree (BaseType::Pointer).Only (-1 ), &CE);
980
+ if (direction & UP)
981
+ updateAnalysis (CE.getOperand (0 ), TypeTree (BaseType::Pointer).Only (-1 ),
982
+ &CE);
983
+ return ;
984
+ }
985
+
986
+ if (direction & DOWN) {
987
+ auto gepData0 = getAnalysis (CE.getOperand (0 )).Data0 ();
988
+ TypeTree result =
989
+ gepData0.ShiftIndices (DL, /* init offset*/ off,
990
+ /* max size*/ maxSize, /* newoffset*/ 0 );
991
+ result.insert ({}, BaseType::Pointer);
992
+ updateAnalysis (&CE, result.Only (-1 ), &CE);
993
+ }
994
+ if (direction & UP) {
995
+ auto pointerData0 = getAnalysis (&CE).Data0 ();
996
+
997
+ TypeTree result =
998
+ pointerData0.ShiftIndices (DL, /* init offset*/ 0 , /* max size*/ -1 ,
999
+ /* new offset*/ off);
1000
+ result.insert ({}, BaseType::Pointer);
1001
+ llvm::errs () << " CE: " << CE << " pdata0: " << pointerData0.str ()
1002
+ << " off: " << off << " res: " << result.str () << " \n " ;
1003
+ updateAnalysis (CE.getOperand (0 ), result.Only (-1 ), &CE);
1004
+ }
1005
+ return ;
1006
+ }
909
1007
auto I = CE.getAsInstruction ();
910
1008
I->insertBefore (fntypeinfo.Function ->getEntryBlock ().getTerminator ());
911
1009
analysis[I] = analysis[&CE];
0 commit comments