There is no way to use all the values of $arr without iterating over it.
I guess you don't want to write a foreach loop but use some PHP function that does the iteration for you.
A simple solution that iterates two times over the array (behind the scene)
This is a possible solution:
$x = array_reduce(
    array_reverse($arr),
    function ($carry, $item) {
        return [$item => $carry];
    },
    1
);
It generates the same result as:
$x = [];
$x['a']['b']['c']['d'] = 1;
Unfortunately it iterates over $arr two times (array_reverse() and array_reduce()).
Another solution that generates a hierarchy of objects
Another approach that generates the required embedding using objects (stdClass) instead of arrays:
$out = new stdClass;
array_reduce(
    $arr,
    function ($carry, $item) {
        $v = new stdClass;
        $carry->{$item} = $v;
        return $v;
    },
    $out
);
It works using a single iteration over $arr but it relies on the way the objects are handled in PHP to work (and this doesn't work with arrays).
PHP handles the objects in a way that makes them look like they are passed by reference. It's a common misconception that the objects are "passed by reference" in PHP but this is not true. A double indirection is responsible for this behaviour.
A recursive solution
function makeArray(array $arr, $initial)
{
    if (! count($arr)) {
        return $initial;
    } else {
        $key = array_shift($arr);
        return [ $key => makeArray($arr, $initial) ];
    }
}
$out = makeArray($arr, 1);
This solution iterates only once over the array and generates a hierarchy of arrays but recursivity is disastrous for large input arrays because it uses a lot of memory.