[llvm] r326188 - Make the LLParser accept call instructions of variables in the program AS

Alexander Richardson via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 27 03:15:11 PST 2018


Author: arichardson
Date: Tue Feb 27 03:15:11 2018
New Revision: 326188

URL: http://llvm.org/viewvc/llvm-project?rev=326188&view=rev
Log:
Make the LLParser accept call instructions of variables in the program AS

Summary:
Since r325479 the DataLayout includes a program address space. However, it
is not possible to use `call %foo` if foo is a `i8(...) addrspace(200)` and
the DataLayout specifies address space 200 as the address space for functions.
With this change the IR parser will still accept variables in the program
address space as well as address space 0 for call and invoke functions.

Reviewers: pcc, arsenm, bjope, dylanmckay, theraven

Reviewed By: dylanmckay

Subscribers: wdng, llvm-commits

Differential Revision: https://reviews.llvm.org/D43645

Added:
    llvm/trunk/test/Assembler/call-nonzero-program-addrspace-2.ll
    llvm/trunk/test/Assembler/call-nonzero-program-addrspace.ll
    llvm/trunk/test/Assembler/invoke-nonzero-program-addrspace.ll
Modified:
    llvm/trunk/lib/AsmParser/LLParser.cpp
    llvm/trunk/lib/AsmParser/LLParser.h

Modified: llvm/trunk/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=326188&r1=326187&r2=326188&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Tue Feb 27 03:15:11 2018
@@ -2612,11 +2612,24 @@ bool LLParser::PerFunctionState::FinishF
   return false;
 }
 
+static bool isValidVariableType(Module *M, Type *Ty, Value *Val, bool IsCall) {
+  if (Val->getType() == Ty)
+    return true;
+  // For calls we also accept variables in the program address space
+  if (IsCall && isa<PointerType>(Ty)) {
+    Type *TyInProgAS = cast<PointerType>(Ty)->getElementType()->getPointerTo(
+        M->getDataLayout().getProgramAddressSpace());
+    if (Val->getType() == TyInProgAS)
+      return true;
+  }
+  return false;
+}
+
 /// GetVal - Get a value with the specified name or ID, creating a
 /// forward reference record if needed.  This can return null if the value
 /// exists but does not have the right type.
 Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty,
-                                          LocTy Loc) {
+                                          LocTy Loc, bool IsCall) {
   // Look this name up in the normal function symbol table.
   Value *Val = F.getValueSymbolTable()->lookup(Name);
 
@@ -2630,7 +2643,8 @@ Value *LLParser::PerFunctionState::GetVa
 
   // If we have the value in the symbol table or fwd-ref table, return it.
   if (Val) {
-    if (Val->getType() == Ty) return Val;
+    if (isValidVariableType(P.M, Ty, Val, IsCall))
+      return Val;
     if (Ty->isLabelTy())
       P.Error(Loc, "'%" + Name + "' is not a basic block");
     else
@@ -2657,7 +2671,8 @@ Value *LLParser::PerFunctionState::GetVa
   return FwdVal;
 }
 
-Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) {
+Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc,
+                                          bool IsCall) {
   // Look this name up in the normal function symbol table.
   Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
 
@@ -2671,7 +2686,8 @@ Value *LLParser::PerFunctionState::GetVa
 
   // If we have the value in the symbol table or fwd-ref table, return it.
   if (Val) {
-    if (Val->getType() == Ty) return Val;
+    if (isValidVariableType(P.M, Ty, Val, IsCall))
+      return Val;
     if (Ty->isLabelTy())
       P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block");
     else
@@ -2762,13 +2778,13 @@ bool LLParser::PerFunctionState::SetInst
 /// forward reference record if needed.
 BasicBlock *LLParser::PerFunctionState::GetBB(const std::string &Name,
                                               LocTy Loc) {
-  return dyn_cast_or_null<BasicBlock>(GetVal(Name,
-                                      Type::getLabelTy(F.getContext()), Loc));
+  return dyn_cast_or_null<BasicBlock>(
+      GetVal(Name, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
 }
 
 BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) {
-  return dyn_cast_or_null<BasicBlock>(GetVal(ID,
-                                      Type::getLabelTy(F.getContext()), Loc));
+  return dyn_cast_or_null<BasicBlock>(
+      GetVal(ID, Type::getLabelTy(F.getContext()), Loc, /*IsCall=*/false));
 }
 
 /// DefineBB - Define the specified basic block, which is either named or
@@ -3387,7 +3403,7 @@ bool LLParser::ParseGlobalValue(Type *Ty
   ValID ID;
   Value *V = nullptr;
   bool Parsed = ParseValID(ID) ||
-                ConvertValIDToValue(Ty, ID, V, nullptr);
+                ConvertValIDToValue(Ty, ID, V, nullptr, /*IsCall=*/false);
   if (V && !(C = dyn_cast<Constant>(V)))
     return Error(ID.Loc, "global values must be constants");
   return Parsed;
@@ -4729,18 +4745,18 @@ bool LLParser::ParseMetadata(Metadata *&
 //===----------------------------------------------------------------------===//
 
 bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
-                                   PerFunctionState *PFS) {
+                                   PerFunctionState *PFS, bool IsCall) {
   if (Ty->isFunctionTy())
     return Error(ID.Loc, "functions are not values, refer to them as pointers");
 
   switch (ID.Kind) {
   case ValID::t_LocalID:
     if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
-    V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
+    V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, IsCall);
     return V == nullptr;
   case ValID::t_LocalName:
     if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
-    V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
+    V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, IsCall);
     return V == nullptr;
   case ValID::t_InlineAsm: {
     if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2))
@@ -4856,7 +4872,7 @@ bool LLParser::parseConstantValue(Type *
   case ValID::t_ConstantStruct:
   case ValID::t_PackedConstantStruct: {
     Value *V;
-    if (ConvertValIDToValue(Ty, ID, V, /*PFS=*/nullptr))
+    if (ConvertValIDToValue(Ty, ID, V, /*PFS=*/nullptr, /*IsCall=*/false))
       return true;
     assert(isa<Constant>(V) && "Expected a constant value");
     C = cast<Constant>(V);
@@ -4873,7 +4889,8 @@ bool LLParser::parseConstantValue(Type *
 bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
   V = nullptr;
   ValID ID;
-  return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS);
+  return ParseValID(ID, PFS) ||
+         ConvertValIDToValue(Ty, ID, V, PFS, /*IsCall=*/false);
 }
 
 bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
@@ -5626,7 +5643,8 @@ bool LLParser::ParseInvoke(Instruction *
 
   // Look up the callee.
   Value *Callee;
-  if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
+  if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
+                          /*IsCall=*/true))
     return true;
 
   // Set up the Attribute for the function.
@@ -6217,7 +6235,8 @@ bool LLParser::ParseCall(Instruction *&I
 
   // Look up the callee.
   Value *Callee;
-  if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS))
+  if (ConvertValIDToValue(PointerType::getUnqual(Ty), CalleeID, Callee, &PFS,
+                          /*IsCall=*/true))
     return true;
 
   // Set up the Attribute for the function.

Modified: llvm/trunk/lib/AsmParser/LLParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.h?rev=326188&r1=326187&r2=326188&view=diff
==============================================================================
--- llvm/trunk/lib/AsmParser/LLParser.h (original)
+++ llvm/trunk/lib/AsmParser/LLParser.h Tue Feb 27 03:15:11 2018
@@ -358,8 +358,8 @@ namespace llvm {
       /// GetVal - Get a value with the specified name or ID, creating a
       /// forward reference record if needed.  This can return null if the value
       /// exists but does not have the right type.
-      Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc);
-      Value *GetVal(unsigned ID, Type *Ty, LocTy Loc);
+      Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc, bool IsCall);
+      Value *GetVal(unsigned ID, Type *Ty, LocTy Loc, bool IsCall);
 
       /// SetInstName - After an instruction is parsed and inserted into its
       /// basic block, this installs its name.
@@ -381,7 +381,7 @@ namespace llvm {
     };
 
     bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
-                             PerFunctionState *PFS);
+                             PerFunctionState *PFS, bool IsCall);
 
     bool parseConstantValue(Type *Ty, Constant *&C);
     bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS);

Added: llvm/trunk/test/Assembler/call-nonzero-program-addrspace-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/call-nonzero-program-addrspace-2.ll?rev=326188&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/call-nonzero-program-addrspace-2.ll (added)
+++ llvm/trunk/test/Assembler/call-nonzero-program-addrspace-2.ll Tue Feb 27 03:15:11 2018
@@ -0,0 +1,11 @@
+; RUN: llvm-as %s -data-layout=P200 -o /dev/null
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+; Check that numbered variables in a nonzero program address space 200 can be used in a call instruction
+
+define i8 @test_unnamed(i8(i32)*, i8(i32) addrspace(200)*) {
+  %first = call i8 %0(i32 0) ; this is fine
+  %second = call i8 %1(i32 0) ; this is also fine if it's the program AS
+  ; CHECK: call-nonzero-program-addrspace-2.ll:[[@LINE-1]]:21: error: '%1' defined with type 'i8 (i32) addrspace(200)*'
+  ret i8 0
+}

Added: llvm/trunk/test/Assembler/call-nonzero-program-addrspace.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/call-nonzero-program-addrspace.ll?rev=326188&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/call-nonzero-program-addrspace.ll (added)
+++ llvm/trunk/test/Assembler/call-nonzero-program-addrspace.ll Tue Feb 27 03:15:11 2018
@@ -0,0 +1,13 @@
+; RUN: llvm-as %s -data-layout=P200 -o /dev/null
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+; Check that variables in a nonzero program address space 200 can be used in a call instruction
+
+define i8 @test(i8(i32)* %fnptr0, i8(i32) addrspace(200)* %fnptr200) {
+  %first = call i8 %fnptr0(i32 0) ; this is fine
+  %second = call i8 %fnptr200(i32 0) ; this is also fine if it's the program AS
+  ; CHECK: call-nonzero-program-addrspace.ll:[[@LINE-1]]:21: error: '%fnptr200' defined with type 'i8 (i32) addrspace(200)*'
+  ret i8 0
+}
+
+declare i32 @__gxx_personality_v0(...)

Added: llvm/trunk/test/Assembler/invoke-nonzero-program-addrspace.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/invoke-nonzero-program-addrspace.ll?rev=326188&view=auto
==============================================================================
--- llvm/trunk/test/Assembler/invoke-nonzero-program-addrspace.ll (added)
+++ llvm/trunk/test/Assembler/invoke-nonzero-program-addrspace.ll Tue Feb 27 03:15:11 2018
@@ -0,0 +1,18 @@
+; RUN: llvm-as %s -data-layout=P200 -o /dev/null
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+; Check that variables in a nonzero program address space 200 can be used in a invoke instruction
+
+define i8 @test_invoke(i8(i32)* %fnptr0, i8(i32) addrspace(200)* %fnptr200) personality i32 (...)* @__gxx_personality_v0 {
+  %first = invoke i8 %fnptr0(i32 0) to label %ok unwind label %lpad ; this is fine
+  %second = invoke i8 %fnptr200(i32 0) to label %ok unwind label %lpad ; this is also fine if it's the program AS
+  ; CHECK: invoke-nonzero-program-addrspace.ll:[[@LINE-1]]:23: error: '%fnptr200' defined with type 'i8 (i32) addrspace(200)*'
+ok:
+  ret i8 0
+lpad:
+    %exn = landingpad {i8*, i32}
+            cleanup
+    unreachable
+}
+
+declare i32 @__gxx_personality_v0(...)




More information about the llvm-commits mailing list