struct sg_table;
 
-enum i915_ggtt_view_type {
-       I915_GGTT_VIEW_NORMAL = 0,
-       I915_GGTT_VIEW_ROTATED,
-       I915_GGTT_VIEW_PARTIAL,
-};
-
 struct intel_rotation_info {
        struct intel_rotation_plane_info {
                /* tiles */
        BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
 }
 
+enum i915_ggtt_view_type {
+       I915_GGTT_VIEW_NORMAL = 0,
+       I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
+       I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
+};
+
+static inline void assert_i915_ggtt_view_type_is_unique(void)
+{
+       /* As we encode the size of each branch inside the union into its type,
+        * we have to be careful that each branch has a unique size.
+        */
+       switch ((enum i915_ggtt_view_type)0) {
+       case I915_GGTT_VIEW_NORMAL:
+       case I915_GGTT_VIEW_PARTIAL:
+       case I915_GGTT_VIEW_ROTATED:
+               /* gcc complains if these are identical cases */
+               break;
+       }
+}
+
 struct i915_ggtt_view {
        enum i915_ggtt_view_type type;
-
        union {
+               /* Members need to contain no holes/padding */
                struct intel_partial_info partial;
                struct intel_rotation_info rotated;
        } params;
 
        if (cmp)
                return cmp;
 
+       BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL != 0);
+       cmp = vma->ggtt_view.type;
        if (!view)
-               return vma->ggtt_view.type;
+               return cmp;
 
-       if (vma->ggtt_view.type != view->type)
-               return vma->ggtt_view.type - view->type;
+       cmp -= view->type;
+       if (cmp)
+               return cmp;
 
-       return memcmp(&vma->ggtt_view.params,
-                     &view->params,
-                     sizeof(view->params));
+       /* ggtt_view.type also encodes its size so that we both distinguish
+        * different views using it as a "type" and also use a compact (no
+        * accessing of uninitialised padding bytes) memcmp without storing
+        * an extra parameter or adding more code.
+        */
+       BUILD_BUG_ON(I915_GGTT_VIEW_NORMAL >= I915_GGTT_VIEW_PARTIAL);
+       BUILD_BUG_ON(I915_GGTT_VIEW_PARTIAL >= I915_GGTT_VIEW_ROTATED);
+       return memcmp(&vma->ggtt_view.params, &view->params, view->type);
 }
 
 int i915_vma_bind(struct i915_vma *vma, enum i915_cache_level cache_level,