+static struct vtn_pointer*
+vtn_align_pointer(struct vtn_builder *b, struct vtn_pointer *ptr,
+ unsigned alignment)
+{
+ if (alignment == 0)
+ return ptr;
+
+ if (!util_is_power_of_two_nonzero(alignment)) {
+ vtn_warn("Provided alignment is not a power of two");
+ alignment = 1 << (ffs(alignment) - 1);
+ }
+
+ /* If this pointer doesn't have a deref, bail. This either means we're
+ * using the old offset+alignment pointers which don't support carrying
+ * alignment information or we're a pointer that is below the block
+ * boundary in our access chain in which case alignment is meaningless.
+ */
+ if (ptr->deref == NULL)
+ return ptr;
+
+ /* Ignore alignment information on logical pointers. This way, we don't
+ * trip up drivers with unnecessary casts.
+ */
+ nir_address_format addr_format = vtn_mode_to_address_format(b, ptr->mode);
+ if (addr_format == nir_address_format_logical)
+ return ptr;
+
+ struct vtn_pointer *copy = ralloc(b, struct vtn_pointer);
+ *copy = *ptr;
+ copy->deref = nir_alignment_deref_cast(&b->nb, ptr->deref, alignment, 0);
+
+ return copy;
+}
+