simeon created this revision.
simeon added reviewers: efriedma, lebedev.ri, arichardson.
Herald added a subscriber: StephenFan.
Herald added a project: All.
simeon requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As an alternative to https://reviews.llvm.org/D150192, we consider using the 
memory region declaration intrinsic, introduced in 
https://reviews.llvm.org/D115274, as another way to propagate the semantics of 
C/C++ array-indexing rules to LLVM IR.

This patch is only only a proof-of-concept at this point, intended to gather 
feedback and bring https://reviews.llvm.org/D115274 back into focus. As was 
mentioned there (and as seen from test results), completing this patch would 
require patching a lot of optimizations. For example, 
`InstructionCombiningPass` works with `GetElementPtrInst`s directly and will 
not recognize an intrinsic call as such. Many other passes such as 
`IndVarSimplifyPass`, `EarlyCSE`, etc., routinely use a switch case or call 
`isa<GetElementPtrInst>()` to detect `GEP`s.

We'd be fine with doing that sort of work, if we get some initial thumbs up 
from the community that this is the way to go. Of course, we're also open to 
trying a different approach if it avoids the apparently unavoidable complexity 
of this one.

Depends on D115274 <https://reviews.llvm.org/D115274>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152275

Files:
  clang/lib/CodeGen/CGExpr.cpp


Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -3936,10 +3936,44 @@
 
     // Propagate the alignment from the array itself to the result.
     QualType arrayType = Array->getType();
-    Addr = emitArraySubscriptGEP(
-        *this, ArrayLV.getAddress(*this), {CGM.getSize(CharUnits::Zero()), 
Idx},
-        E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
-        E->getExprLoc(), &arrayType, E->getBase());
+
+    Address ArrayLVAddr = ArrayLV.getAddress(*this);
+
+    if (!getLangOpts().isSignedOverflowDefined() && 
+        // ISO/IEC 9899:TC3, 6.5.6.8
+        (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
+        getContext().getAsConstantArrayType(arrayType)) {
+      auto *CAT = getContext().getAsConstantArrayType(arrayType);
+      uint64_t BoundedRegionSize = (Idx->getType()->getScalarSizeInBits() / 8) 
* 
+          CAT->getSize().getZExtValue();
+
+      Address BeginOff = emitArraySubscriptGEP(
+          *this, ArrayLVAddr, 
+          {CGM.getSize(CharUnits::Zero()), CGM.getSize(CharUnits::Zero())},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), 
SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+
+      llvm::Function *F = 
CGM.getIntrinsic(llvm::Intrinsic::memory_region_decl, 
+          BeginOff.getPointer()->getType());
+      llvm::Value *Call = Builder.CreateCall(F,
+          {BeginOff.getPointer(), 
+          llvm::ConstantInt::get(Int64Ty, 0), 
+          llvm::ConstantInt::get(Int64Ty, BoundedRegionSize)},
+          "arrayidx.bounded");
+      Address RetAddr(Call, BeginOff.getElementType(), 
+          ArrayLVAddr.getAlignment());
+
+      Addr = emitArraySubscriptGEP(
+          *this, RetAddr, {Idx},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), 
SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+    } else {
+      Addr = emitArraySubscriptGEP(
+          *this, ArrayLVAddr, {CGM.getSize(CharUnits::Zero()), Idx},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), 
SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+    }
+        
     EltBaseInfo = ArrayLV.getBaseInfo();
     EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
   } else {


Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -3936,10 +3936,44 @@
 
     // Propagate the alignment from the array itself to the result.
     QualType arrayType = Array->getType();
-    Addr = emitArraySubscriptGEP(
-        *this, ArrayLV.getAddress(*this), {CGM.getSize(CharUnits::Zero()), Idx},
-        E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
-        E->getExprLoc(), &arrayType, E->getBase());
+
+    Address ArrayLVAddr = ArrayLV.getAddress(*this);
+
+    if (!getLangOpts().isSignedOverflowDefined() && 
+        // ISO/IEC 9899:TC3, 6.5.6.8
+        (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
+        getContext().getAsConstantArrayType(arrayType)) {
+      auto *CAT = getContext().getAsConstantArrayType(arrayType);
+      uint64_t BoundedRegionSize = (Idx->getType()->getScalarSizeInBits() / 8) * 
+          CAT->getSize().getZExtValue();
+
+      Address BeginOff = emitArraySubscriptGEP(
+          *this, ArrayLVAddr, 
+          {CGM.getSize(CharUnits::Zero()), CGM.getSize(CharUnits::Zero())},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+
+      llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::memory_region_decl, 
+          BeginOff.getPointer()->getType());
+      llvm::Value *Call = Builder.CreateCall(F,
+          {BeginOff.getPointer(), 
+          llvm::ConstantInt::get(Int64Ty, 0), 
+          llvm::ConstantInt::get(Int64Ty, BoundedRegionSize)},
+          "arrayidx.bounded");
+      Address RetAddr(Call, BeginOff.getElementType(), 
+          ArrayLVAddr.getAlignment());
+
+      Addr = emitArraySubscriptGEP(
+          *this, RetAddr, {Idx},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+    } else {
+      Addr = emitArraySubscriptGEP(
+          *this, ArrayLVAddr, {CGM.getSize(CharUnits::Zero()), Idx},
+          E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices,
+          E->getExprLoc(), &arrayType, E->getBase());
+    }
+        
     EltBaseInfo = ArrayLV.getBaseInfo();
     EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType());
   } else {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to