#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ get_double_grid_address(long *, long *, long const *);
long get_double_grid_index(long *, long const *, long const *);
int /*<<< orphan*/ get_grid_address_from_index(long *, long const,
                                               long const *);
int /*<<< orphan*/ mat_multiply_matrix_vector_l3(long *, long **, long *);
long rotate_grid_index(const long grid_index, long rotation[3][3],
                       const long D_diag[3], const long PS[3]) {
  long adrs[3], dadrs[3], dadrs_rot[3];
  get_grid_address_from_index(adrs, grid_index, D_diag);
  get_double_grid_address(dadrs, adrs, PS);
  mat_multiply_matrix_vector_l3(dadrs_rot, rotation, dadrs);
  return get_double_grid_index(dadrs_rot, D_diag, PS);
}


x86 assembly (clang, -O0):
<rotate_grid_index>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
lea    -0x40(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    -0x18(%rbp),%rdx
call   1030 <get_grid_address_from_index@plt>
lea    -0x60(%rbp),%rdi
lea    -0x40(%rbp),%rsi
mov    -0x20(%rbp),%rdx
call   1050 <get_double_grid_address@plt>
lea    -0x80(%rbp),%rdi
mov    -0x10(%rbp),%rsi
lea    -0x60(%rbp),%rdx
call   1060 <mat_multiply_matrix_vector_l3@plt>
lea    -0x80(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x20(%rbp),%rdx
call   1040 <get_double_grid_index@plt>
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rotate_grid_index>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x60,%rsp
mov    %rcx,%r14
mov    %rdx,%rbx
mov    %rsi,%r15
mov    %rdi,%rsi
lea    0x40(%rsp),%r12
mov    %r12,%rdi
call   1030 <get_grid_address_from_index@plt>
lea    0x20(%rsp),%r13
mov    %r13,%rdi
mov    %r12,%rsi
mov    %r14,%rdx
call   1050 <get_double_grid_address@plt>
mov    %rsp,%r12
mov    %r12,%rdi
mov    %r15,%rsi
mov    %r13,%rdx
call   1060 <mat_multiply_matrix_vector_l3@plt>
mov    %r12,%rdi
mov    %rbx,%rsi
mov    %r14,%rdx
call   1040 <get_double_grid_index@plt>
add    $0x60,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i64 @rotate_grid_index(i64 %0, [3 x i64]* %1, i64* %2, i64* %3) {
%5 = alloca i64
%6 = alloca [3 x i64]*
%7 = alloca i64*
%8 = alloca i64*
%9 = alloca [3 x i64]
%10 = alloca [3 x i64]
%11 = alloca [3 x i64]
store i64 %0, i64* %5
store [3 x i64]* %1, [3 x i64]** %6
store i64* %2, i64** %7
store i64* %3, i64** %8
%12 = getelementptr inbounds [3 x i64], [3 x i64]* %9, i64 0, i64 0
%13 = load i64, i64* %5
%14 = load i64*, i64** %7
%15 = call i32 @get_grid_address_from_index(i64* %12, i64 %13, i64* %14)
%16 = getelementptr inbounds [3 x i64], [3 x i64]* %10, i64 0, i64 0
%17 = getelementptr inbounds [3 x i64], [3 x i64]* %9, i64 0, i64 0
%18 = load i64*, i64** %8
%19 = call i32 @get_double_grid_address(i64* %16, i64* %17, i64* %18)
%20 = getelementptr inbounds [3 x i64], [3 x i64]* %11, i64 0, i64 0
%21 = load [3 x i64]*, [3 x i64]** %6
%22 = bitcast [3 x i64]* %21 to i64**
%23 = getelementptr inbounds [3 x i64], [3 x i64]* %10, i64 0, i64 0
%24 = call i32 @mat_multiply_matrix_vector_l3(i64* %20, i64** %22, i64* %23)
%25 = getelementptr inbounds [3 x i64], [3 x i64]* %11, i64 0, i64 0
%26 = load i64*, i64** %7
%27 = load i64*, i64** %8
%28 = call i64 @get_double_grid_index(i64* %25, i64* %26, i64* %27)
ret i64 %28
}

LLVM IR (-O2):
define i64 @rotate_grid_index(i64 %0, [3 x i64]* %1, i64* %2, i64* %3) {
%5 = alloca [3 x i64]
%6 = alloca [3 x i64]
%7 = alloca [3 x i64]
%8 = bitcast [3 x i64]* %5 to i8*
%9 = bitcast [3 x i64]* %6 to i8*
%10 = bitcast [3 x i64]* %7 to i8*
%11 = getelementptr inbounds [3 x i64], [3 x i64]* %5, i64 0, i64 0
%12 = call i32 @get_grid_address_from_index(i64* %11, i64 %0, i64* %2)
%13 = getelementptr inbounds [3 x i64], [3 x i64]* %6, i64 0, i64 0
%14 = call i32 @get_double_grid_address(i64* %13, i64* %11, i64* %3)
%15 = getelementptr inbounds [3 x i64], [3 x i64]* %7, i64 0, i64 0
%16 = bitcast [3 x i64]* %1 to i64**
%17 = call i32 @mat_multiply_matrix_vector_l3(i64* %15, i64** %16, i64* %13)
%18 = call i64 @get_double_grid_index(i64* %15, i64* %2, i64* %3)
ret i64 %18
}