Repository: pytorch
Issue: Improving expand w/ unbacked symints
Labels: triaged,has workaround,oncall: pt2,module: dynamic shapes

### 🐛 Describe the bug

```
  @skipCUDAIf(not HAS_CUDA, "requires cuda")
  @dynamo_config.patch({"capture_scalar_outputs": True})
  def test_expand(self, device):
      mm_fn = torch.bmm
      def fn(x, w, repeats):
          u0 = repeats.item()
          torch._check_is_size(u0)
          x_unbacked = x.expand(-1, u0)    # [16, u0]
          # But x.unsqueeze(1).expand(-1, u0) works
      
      example_inputs = (
          torch.randn(16).cuda(),
          torch.tensor(100).cuda(),
      )
      actual = torch.compile(fn, fullgraph=True)(*example_inputs)

```

We hit this code during `expand`.
https://github.com/pytorch/pytorch/blob/c0b40ab42e38a208351911496b7153511304f8da/torch/_refs/__init__.py#L2939-L2944

In this scenario, we have `requested_length = u0` and `x = 16`. All three of these checks will resolve to false or fail. 

However we know that `x.unsqueeze(1).expand(-1, u0)` works, so why can't `x.expand(-1, u0)` work? This has me wondering, if we can somehow tell Dynamo that this is fine without a `torch._check`.

### Error logs

```
======================================================================
ERROR: test_bmm_cuda (__main__.TestUnbackedSymintsCUDA)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/data/users/colinpeppler/pytorch/torch/_dynamo/utils.py", line 1905, in run_node
    return getattr(args[0], node.target)(*args[1:], **kwargs)
  File "/data/users/colinpeppler/pytorch/torch/utils/_stats.py", line 21, in wrapper
    return fn(*args, **kwargs)
  File "/data/users/colinpeppler/pytorch/torch/_subclasses/fake_tensor.py", line 1061, in __torch_dispatch__
    return self.dispatch(func, types, args, kwargs)
  File "/data/users/colinpeppler/pytorch/torch/_subclasses/fake_tensor.py", line 1450, in dispatch
    return self._cached_dispatch_impl(func, types, args, kwargs)
  File "/data/users/colinpeppler/pytorch/torch/_subclasses/fake_tensor.py", line 1153, in _cached_dispatch_impl
    output = self._dispatch_impl(func, types, args, kwargs)
  File "/data/users/colinpeppler/pytorch/torch/_subclasses/fake_tensor.py", line 1690, in _dispatch_impl
    return decomposition_table[func](*args, **kwargs)
  File "/data/users/colinpeppler/pytorch/torch/_refs/__init__.py", line 2937, in expand
    guard_size_oblivious(requested_length == x)
  File "/data/users/colinpeppler/pytorch/torch/fx/experimental/symbolic_shapes.py", line 248, in guard_size_oblivious
    return expr.node.guard_size_oblivious("", 0)
  File "/data/users/colinpeppler/pytorch/torch/fx/experimental/sym_node.py", line 466, in guard_size_oblivious
    r = self.shape_env.evaluate_expr(
  File "/data/users/colinpeppler/pytorch/torch/fx/experimental/recording.py", line 245, in wrapper
    return fn(*args, **kwargs)
  File "/data/users/colinpeppler/pytorch/torch/fx/experimental/symbolic_shapes.py", line 5197, in evaluate_expr
    raise self._make_data_dependent_error(
torch.fx.experimental.symbolic_shapes.GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0, 1) (unhinted: Eq(u0, 1)).  (Size-like symbols: none)

Potential framework code culprit (scroll up for full backtrace):
  File "/data/users/colinpeppler/pytorch/torch/_refs/__init__.py", line 2937, in expand
    guard_size_oblivious(requested_length == x)
```

### Minified repro

_No response_

### Versions

N/A

cc @ezyang @anijain2305 @chauhang @penguinwu