diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 62e0674fd9173368fc39ab88c6ba009db3d3551d..c3d0acb57e85417ef833db0c19fa10fc46f8d8f3 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -508,6 +508,12 @@ public:
         return flat || smooth || nopersp;
 #endif
     }
+#ifdef AMD_EXTENSIONS
+    bool isExplicitInterpolation() const
+    {
+        return explicitInterp;
+    }
+#endif
     bool isAuxiliary() const
     {
         return centroid || patch || sample;
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index fc653f4c3aea3427c5a394d7d0d26772d1a1068e..0d9cea7b3474e0950fa558c2c79722176bb16564 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -1608,6 +1608,23 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
             if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn)
                 error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), "");
         }
+
+#ifdef AMD_EXTENSIONS
+        if (callNode.getOp() == EOpInterpolateAtVertex) {
+            if (!arg0->getType().getQualifier().isExplicitInterpolation())
+                error(loc, "argument must be qualified as __explicitInterpAMD in", "interpolant", "");
+            else {
+                if (! (*argp)[1]->getAsConstantUnion())
+                    error(loc, "argument must be compile-time constant", "vertex index", "");
+                else {
+                    unsigned vertexIdx = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getUConst();
+                    if (vertexIdx > 2)
+                        error(loc, "must be in the range [0, 2]", "vertex index", "");
+                }
+            }
+        }
+#endif
+
         break;
 
     case EOpEmitStreamVertex: