[llvm-commits] [llvm] r77259 - in /llvm/trunk: docs/LangRef.html include/llvm/Bitcode/LLVMBitCodes.h include/llvm/Operator.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/VMCore/AsmWriter.cpp test/Assembler/flags-plain.ll test/Assembler/flags.ll

Dan Gohman gohman at apple.com
Mon Jul 27 14:53:46 PDT 2009


Author: djg
Date: Mon Jul 27 16:53:46 2009
New Revision: 77259

URL: http://llvm.org/viewvc/llvm-project?rev=77259&view=rev
Log:
Add a new keyword 'inbounds' for use with getelementptr. See the
LangRef.html changes for details.

Modified:
    llvm/trunk/docs/LangRef.html
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/include/llvm/Operator.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLToken.h
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/VMCore/AsmWriter.cpp
    llvm/trunk/test/Assembler/flags-plain.ll
    llvm/trunk/test/Assembler/flags.ll

Modified: llvm/trunk/docs/LangRef.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/docs/LangRef.html (original)
+++ llvm/trunk/docs/LangRef.html Mon Jul 27 16:53:46 2009
@@ -2091,6 +2091,7 @@
       instruction</a>.</dd>
 
   <dt><b><tt>getelementptr ( CSTPTR, IDX0, IDX1, ... )</tt></b></dt>
+  <dt><b><tt>getelementptr inbounds ( CSTPTR, IDX0, IDX1, ... )</tt></b></dt>
   <dd>Perform the <a href="#i_getelementptr">getelementptr operation</a> on
       constants.  As with the <a href="#i_getelementptr">getelementptr</a>
       instruction, the index list may have zero or more indexes, which are
@@ -3902,6 +3903,7 @@
 <h5>Syntax:</h5>
 <pre>
   <result> = getelementptr <pty>* <ptrval>{, <ty> <idx>}*
+  <result> = getelementptr inbounds <pty>* <ptrval>{, <ty> <idx>}*
 </pre>
 
 <h5>Overview:</h5>
@@ -3990,6 +3992,20 @@
   }
 </pre>
 
+<p>If the <tt>inbounds</tt> keyword is present, the result value of the
+   <tt>getelementptr</tt> is undefined if the base pointer is not pointing
+   into an allocated object, or if any of the addresses formed by successive
+   addition of the offsets implied by the indices to the base address is
+   outside of the allocated object into which the base pointer points.</p>
+
+<p>If the <tt>inbounds</tt> keyword is not present, the offsets are added to
+   the base address with silently-wrapping two's complement arithmetic, and
+   the result value of the <tt>getelementptr</tt> may be outside the object
+   pointed to by the base pointer. The result value may not necessarily be
+   used to access memory though, even if it happens to point into allocated
+   storage. See the <a href="#pointeraliasing">Pointer Aliasing Rules</a>
+   section for more information.</p>
+
 <p>The getelementptr instruction is often confusing.  For some more insight into
    how it works, see <a href="GetElementPtr.html">the getelementptr FAQ</a>.</p>
 

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Mon Jul 27 16:53:46 2009
@@ -132,7 +132,8 @@
     CST_CODE_CE_SHUFFLEVEC = 16,  // CE_SHUFFLEVEC: [opval, opval, opval]
     CST_CODE_CE_CMP        = 17,  // CE_CMP:        [opty, opval, opval, pred]
     CST_CODE_INLINEASM     = 18,  // INLINEASM:     [sideeffect,asmstr,conststr]
-    CST_CODE_CE_SHUFVEC_EX = 19   // SHUFVEC_EX:    [opty, opval, opval, opval]
+    CST_CODE_CE_SHUFVEC_EX = 19,  // SHUFVEC_EX:    [opty, opval, opval, opval]
+    CST_CODE_CE_INBOUNDS_GEP = 20 // INBOUNDS_GEP:  [n x operands]
   };
 
   /// CastOpcodes - These are values used in the bitcode files to encode which
@@ -229,7 +230,8 @@
     // support legacy vicmp/vfcmp instructions.
     FUNC_CODE_INST_CMP2        = 28, // CMP2:       [opty, opval, opval, pred]
     // new select on i1 or [N x i1]
-    FUNC_CODE_INST_VSELECT     = 29  // VSELECT:    [ty,opval,opval,predty,pred]
+    FUNC_CODE_INST_VSELECT     = 29, // VSELECT:    [ty,opval,opval,predty,pred]
+    FUNC_CODE_INST_INBOUNDS_GEP = 30 // INBOUNDS_GEP: [n x operands]
   };
 } // End bitc namespace
 } // End llvm namespace

Modified: llvm/trunk/include/llvm/Operator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Operator.h?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Operator.h (original)
+++ llvm/trunk/include/llvm/Operator.h Mon Jul 27 16:53:46 2009
@@ -181,6 +181,15 @@
 
 class GEPOperator : public Operator {
 public:
+  /// isInBounds - Test whether this is an inbounds GEP, as defined
+  /// by LangRef.html.
+  bool isInBounds() const {
+    return SubclassOptionalData & (1 << 0);
+  }
+  void setIsInBounds(bool B) {
+    SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
+  }
+
   inline op_iterator       idx_begin()       { return op_begin()+1; }
   inline const_op_iterator idx_begin() const { return op_begin()+1; }
   inline op_iterator       idx_end()         { return op_end(); }

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Jul 27 16:53:46 2009
@@ -504,6 +504,7 @@
   KEYWORD(nuw);
   KEYWORD(nsw);
   KEYWORD(exact);
+  KEYWORD(inbounds);
   KEYWORD(align);
   KEYWORD(addrspace);
   KEYWORD(section);

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Jul 27 16:53:46 2009
@@ -457,7 +457,7 @@
 /// Aliasee
 ///   ::= TypeAndValue
 ///   ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
-///   ::= 'getelementptr' '(' ... ')'
+///   ::= 'getelementptr' 'inbounds'? '(' ... ')'
 ///
 /// Everything through visibility has already been parsed.
 ///
@@ -2039,7 +2039,11 @@
   case lltok::kw_select: {
     unsigned Opc = Lex.getUIntVal();
     SmallVector<Constant*, 16> Elts;
+    bool InBounds = false;
     Lex.Lex();
+    if (Opc == Instruction::GetElementPtr)
+      if (EatIfPresent(lltok::kw_inbounds))
+        InBounds = true;
     if (ParseToken(lltok::lparen, "expected '(' in constantexpr") ||
         ParseGlobalValueVector(Elts) ||
         ParseToken(lltok::rparen, "expected ')' in constantexpr"))
@@ -2055,6 +2059,8 @@
         return Error(ID.Loc, "invalid indices for getelementptr");
       ID.ConstantVal = Context.getConstantExprGetElementPtr(Elts[0],
                                               Elts.data() + 1, Elts.size() - 1);
+      if (InBounds)
+        cast<GEPOperator>(ID.ConstantVal)->setIsInBounds(true);
     } else if (Opc == Instruction::Select) {
       if (Elts.size() != 3)
         return Error(ID.Loc, "expected three operands to select");
@@ -3368,9 +3374,14 @@
 }
 
 /// ParseGetElementPtr
-///   ::= 'getelementptr' TypeAndValue (',' TypeAndValue)*
+///   ::= 'getelementptr' 'inbounds'? TypeAndValue (',' TypeAndValue)*
 bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
   Value *Ptr, *Val; LocTy Loc, EltLoc;
+  bool InBounds = false;
+
+  if (EatIfPresent(lltok::kw_inbounds))
+    InBounds = true;
+
   if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
   
   if (!isa<PointerType>(Ptr->getType()))
@@ -3388,6 +3399,8 @@
                                          Indices.begin(), Indices.end()))
     return Error(Loc, "invalid getelementptr indices");
   Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
+  if (InBounds)
+    cast<GEPOperator>(Inst)->setIsInBounds(true);
   return false;
 }
 

Modified: llvm/trunk/lib/AsmParser/LLToken.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLToken.h (original)
+++ llvm/trunk/lib/AsmParser/LLToken.h Mon Jul 27 16:53:46 2009
@@ -54,6 +54,7 @@
     kw_nuw,
     kw_nsw,
     kw_exact,
+    kw_inbounds,
     kw_align,
     kw_addrspace,
     kw_section,

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Jul 27 16:53:46 2009
@@ -997,6 +997,7 @@
       }
       break;
     }  
+    case bitc::CST_CODE_CE_INBOUNDS_GEP:
     case bitc::CST_CODE_CE_GEP: {  // CE_GEP:        [n x operands]
       if (Record.size() & 1) return Error("Invalid CE_GEP record");
       SmallVector<Constant*, 16> Elts;
@@ -1007,6 +1008,8 @@
       }
       V = Context.getConstantExprGetElementPtr(Elts[0], &Elts[1], 
                                                Elts.size()-1);
+      if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
+        cast<GEPOperator>(V)->setIsInBounds(true);
       break;
     }
     case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
@@ -1556,6 +1559,7 @@
       I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy);
       break;
     }
+    case bitc::FUNC_CODE_INST_INBOUNDS_GEP:
     case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
       unsigned OpNum = 0;
       Value *BasePtr;
@@ -1571,6 +1575,8 @@
       }
 
       I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
+      if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
+        cast<GEPOperator>(I)->setIsInBounds(true);
       break;
     }
       

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Jul 27 16:53:46 2009
@@ -706,6 +706,8 @@
         break;
       case Instruction::GetElementPtr:
         Code = bitc::CST_CODE_CE_GEP;
+        if (cast<GEPOperator>(C)->isInBounds())
+          Code = bitc::CST_CODE_CE_INBOUNDS_GEP;
         for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) {
           Record.push_back(VE.getTypeID(C->getOperand(i)->getType()));
           Record.push_back(VE.getValueID(C->getOperand(i)));
@@ -829,6 +831,8 @@
 
   case Instruction::GetElementPtr:
     Code = bitc::FUNC_CODE_INST_GEP;
+    if (cast<GEPOperator>(&I)->isInBounds())
+      Code = bitc::FUNC_CODE_INST_INBOUNDS_GEP;
     for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
       PushValueAndType(I.getOperand(i), InstID, Vals, VE);
     break;

Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Mon Jul 27 16:53:46 2009
@@ -854,6 +854,9 @@
   } else if (const SDivOperator *Div = dyn_cast<SDivOperator>(U)) {
     if (Div->isExact())
       Out << " exact";
+  } else if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
+    if (GEP->isInBounds())
+      Out << " inbounds";
   }
 }
 

Modified: llvm/trunk/test/Assembler/flags-plain.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags-plain.ll?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/test/Assembler/flags-plain.ll (original)
+++ llvm/trunk/test/Assembler/flags-plain.ll Mon Jul 27 16:53:46 2009
@@ -21,3 +21,8 @@
 ; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
 	ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
 }
+
+define i64* @gep_plain_ce() {
+; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
+        ret i64* getelementptr (i64* @addr, i64 171)
+}

Modified: llvm/trunk/test/Assembler/flags.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/flags.ll?rev=77259&r1=77258&r2=77259&view=diff

==============================================================================
--- llvm/trunk/test/Assembler/flags.ll (original)
+++ llvm/trunk/test/Assembler/flags.ll Mon Jul 27 16:53:46 2009
@@ -104,6 +104,18 @@
 	ret i64 %z
 }
 
+define i64* @gep_nw(i64* %p, i64 %x) {
+; CHECK: %z = getelementptr inbounds i64* %p, i64 %x
+	%z = getelementptr inbounds i64* %p, i64 %x
+        ret i64* %z
+}
+
+define i64* @gep_plain(i64* %p, i64 %x) {
+; CHECK: %z = getelementptr i64* %p, i64 %x
+	%z = getelementptr i64* %p, i64 %x
+        ret i64* %z
+}
+
 define i64 @add_both_ce() {
 ; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
 	ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
@@ -123,3 +135,10 @@
 ; CHECK: ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
 	ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91)
 }
+
+define i64* @gep_nw_ce() {
+; CHECK: ret i64* getelementptr inbounds (i64* @addr, i64 171)
+        ret i64* getelementptr inbounds (i64* @addr, i64 171)
+}
+
+





More information about the llvm-commits mailing list