// File: dsharlet[P]array/test/shape.cpp
// Function: nda::test_shape_optimize_body()
TEST(shape_optimize) {
  dim<> dummy_dim(0, 1, 0);

  shape_of_rank<3> a({0, 5, 21}, {0, 7, 3}, {5, 3, 1});
  shape_of_rank<3> a_optimized({5, 105, 1}, dummy_dim, dummy_dim);
  assert_shapes_eq(internal::dynamic_optimize_shape(a), a_optimized);

  shape_of_rank<3> b({0, 5, 42}, {3, 7, 6}, {0, 3, 2});
  shape_of_rank<3> b_optimized({9, 105, 2}, dummy_dim, dummy_dim);
  assert_shapes_eq(internal::dynamic_optimize_shape(b), b_optimized);

  shape_of_rank<3> c({0, 5, 40}, {0, 7, 3}, {0, 2, 1});
  shape_of_rank<3> c_optimized({0, 2, 1}, {0, 7, 3}, {0, 5, 40});
  assert_shapes_eq(internal::dynamic_optimize_shape(c), c_optimized);

  shape_of_rank<3> d({0, 5, 28}, {0, 7, 4}, {0, 3, 1});
  shape_of_rank<3> d_optimized({0, 3, 1}, {0, 35, 4}, dummy_dim);
  assert_shapes_eq(internal::dynamic_optimize_shape(d), d_optimized);

  shape_of_rank<10> e(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
  e.resolve();
  shape_of_rank<10> e2 = reorder<9, 5, 3, 7, 2, 8, 4, 6, 0, 1>(e);
  shape_of_rank<10> e_optimized({0, 3628800, 1}, dummy_dim, dummy_dim, dummy_dim, dummy_dim,
      dummy_dim, dummy_dim, dummy_dim, dummy_dim, dummy_dim);
  assert_shapes_eq(internal::dynamic_optimize_shape(e), e_optimized);
  assert_shapes_eq(internal::dynamic_optimize_shape(e2), e_optimized);

  shape_of_rank<2> f({0, 2}, {1, 2});
  shape_of_rank<2> f_optimized({2, 4, 1}, dummy_dim);
  f.resolve();
  assert_shapes_eq(internal::dynamic_optimize_shape(f), f_optimized);

  shape_of_rank<2> g({1, 2}, {1, 2});
  shape_of_rank<2> g_optimized({3, 4, 1}, dummy_dim);
  g.resolve();
  assert_shapes_eq(internal::dynamic_optimize_shape(g), g_optimized);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xbe0, %rsp            # imm = 0xBE0
leaq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movl $0x1, %edx
movq %rcx, %rsi
callq 0x10c60
leaq -0x78(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x5, %edx
movl $0x15, %ecx
callq 0x10c60
leaq -0x90(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x7, %edx
movl $0x3, %ecx
callq 0x10c60
leaq -0xa8(%rbp), %rdi
movl $0x5, %esi
movl $0x3, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0x60(%rbp), %rdi
leaq -0x78(%rbp), %rsi
leaq -0x90(%rbp), %rdx
leaq -0xa8(%rbp), %rcx
callq 0x36640
leaq -0x108(%rbp), %rdi
movl $0x5, %esi
movl $0x69, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0xf0(%rbp), %rdi
leaq -0x108(%rbp), %rsi
leaq -0x18(%rbp), %rcx
movq %rcx, %rdx
callq 0x36640
leaq -0x150(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x38240
leaq -0x150(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x18b570
leaq -0x1b0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x5, %edx
movl $0x2a, %ecx
callq 0x10c60
leaq -0x1c8(%rbp), %rdi
movl $0x3, %esi
movl $0x7, %edx
movl $0x6, %ecx
callq 0x10c60
leaq -0x1e0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x3, %edx
movl $0x2, %ecx
callq 0x10c60
leaq -0x198(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
leaq -0x1c8(%rbp), %rdx
leaq -0x1e0(%rbp), %rcx
callq 0x36640
leaq -0x240(%rbp), %rdi
movl $0x9, %esi
movl $0x69, %edx
movl $0x2, %ecx
callq 0x10c60
leaq -0x228(%rbp), %rdi
leaq -0x240(%rbp), %rsi
leaq -0x18(%rbp), %rcx
movq %rcx, %rdx
callq 0x36640
leaq -0x288(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x38240
leaq -0x288(%rbp), %rdi
leaq -0x228(%rbp), %rsi
callq 0x18b570
leaq -0x2e8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x5, %edx
movl $0x28, %ecx
callq 0x10c60
leaq -0x300(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x7, %edx
movl $0x3, %ecx
callq 0x10c60
leaq -0x318(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0x2d0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
leaq -0x300(%rbp), %rdx
leaq -0x318(%rbp), %rcx
callq 0x36640
leaq -0x378(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0x390(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x7, %edx
movl $0x3, %ecx
callq 0x10c60
leaq -0x3a8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x5, %edx
movl $0x28, %ecx
callq 0x10c60
leaq -0x360(%rbp), %rdi
leaq -0x378(%rbp), %rsi
leaq -0x390(%rbp), %rdx
leaq -0x3a8(%rbp), %rcx
callq 0x36640
leaq -0x3f0(%rbp), %rdi
leaq -0x2d0(%rbp), %rsi
callq 0x38240
leaq -0x3f0(%rbp), %rdi
leaq -0x360(%rbp), %rsi
callq 0x18b570
leaq -0x450(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x5, %edx
movl $0x1c, %ecx
callq 0x10c60
leaq -0x468(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x7, %edx
movl $0x4, %ecx
callq 0x10c60
leaq -0x480(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x3, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0x438(%rbp), %rdi
leaq -0x450(%rbp), %rsi
leaq -0x468(%rbp), %rdx
leaq -0x480(%rbp), %rcx
callq 0x36640
leaq -0x4e0(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x3, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0x4f8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x23, %edx
movl $0x4, %ecx
callq 0x10c60
leaq -0x4c8(%rbp), %rdi
leaq -0x4e0(%rbp), %rsi
leaq -0x4f8(%rbp), %rdx
leaq -0x18(%rbp), %rcx
callq 0x36640
leaq -0x540(%rbp), %rdi
leaq -0x438(%rbp), %rsi
callq 0x38240
leaq -0x540(%rbp), %rdi
leaq -0x4c8(%rbp), %rsi
callq 0x18b570
leaq -0x630(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movl $0x3, %ecx
movl $0x4, %r8d
movl $0x5, %r9d
movl $0x6, (%rsp)
movl $0x7, 0x8(%rsp)
movl $0x8, 0x10(%rsp)
movl $0x9, 0x18(%rsp)
movl $0xa, 0x20(%rsp)
callq 0x18b5a0
leaq -0x630(%rbp), %rdi
callq 0x18b640
leaq -0x720(%rbp), %rdi
leaq -0x630(%rbp), %rsi
callq 0x18b660
leaq -0x828(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x375f00, %edx         # imm = 0x375F00
movl $0x1, %ecx
callq 0x10c60
leaq -0x810(%rbp), %rdi
leaq -0x828(%rbp), %rsi
leaq -0x18(%rbp), %rax
movq %rax, %rdx
movq %rax, %rcx
movq %rax, %r8
movq %rax, %r9
movq %rax, (%rsp)
movq %rax, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x18b990
leaq -0x918(%rbp), %rdi
leaq -0x630(%rbp), %rsi
callq 0x18ba80
leaq -0x918(%rbp), %rdi
leaq -0x810(%rbp), %rsi
callq 0x18ba50
leaq -0xa08(%rbp), %rdi
leaq -0x720(%rbp), %rsi
callq 0x18ba80
leaq -0xa08(%rbp), %rdi
leaq -0x810(%rbp), %rsi
callq 0x18ba50
leaq -0xa50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
callq 0x10c60
leaq -0xa68(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
callq 0x10c60
leaq -0xa38(%rbp), %rdi
leaq -0xa50(%rbp), %rsi
leaq -0xa68(%rbp), %rdx
callq 0x11310
leaq -0xab0(%rbp), %rdi
movl $0x2, %esi
movl $0x4, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0xa98(%rbp), %rdi
leaq -0xab0(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x11310
leaq -0xa38(%rbp), %rdi
callq 0x1a1a0
leaq -0xae0(%rbp), %rdi
leaq -0xa38(%rbp), %rsi
callq 0x1aad0
leaq -0xae0(%rbp), %rdi
leaq -0xa98(%rbp), %rsi
callq 0x18bf50
leaq -0xb28(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
callq 0x10c60
leaq -0xb40(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %edx
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
callq 0x10c60
leaq -0xb10(%rbp), %rdi
leaq -0xb28(%rbp), %rsi
leaq -0xb40(%rbp), %rdx
callq 0x11310
leaq -0xb88(%rbp), %rdi
movl $0x3, %esi
movl $0x4, %edx
movl $0x1, %ecx
callq 0x10c60
leaq -0xb70(%rbp), %rdi
leaq -0xb88(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x11310
leaq -0xb10(%rbp), %rdi
callq 0x1a1a0
leaq -0xbb8(%rbp), %rdi
leaq -0xb10(%rbp), %rsi
callq 0x1aad0
leaq -0xbb8(%rbp), %rdi
leaq -0xb70(%rbp), %rsi
callq 0x18bf50
addq $0xbe0, %rsp            # imm = 0xBE0
popq %rbp
retq
nopw (%rax,%rax)