#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 */
struct shape_information_data {
  int dummy;
};
struct low_level_shape_definition {
  int dummy;
};
struct collection_definition {
  int dummy;
};
typedef short collection_code;

/* Variables and functions */
struct collection_definition *get_collection_definition(short);
struct low_level_shape_definition *get_low_level_shape_definition(short, short);
struct shape_information_data *
extended_get_shape_information(short collection_code,
                               short low_level_shape_index) {
  short collection_index = ((collection_code) & ((1 << 5) - 1));
  struct low_level_shape_definition *low_level_shape;
  struct collection_definition *collection;
  collection = get_collection_definition(collection_index);
  low_level_shape =
      get_low_level_shape_definition(collection_index, low_level_shape_index);
  return (struct shape_information_data *)low_level_shape;
}


x86 assembly (clang, -O0):
<extended_get_shape_information>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %si,%ax
mov    %di,%cx
mov    %cx,-0x2(%rbp)
mov    %ax,-0x4(%rbp)
movswl -0x2(%rbp),%eax
and    $0x1f,%eax
mov    %ax,-0x6(%rbp)
movswl -0x6(%rbp),%edi
call   1040 <get_collection_definition@plt>
mov    %rax,-0x18(%rbp)
mov    -0x6(%rbp),%ax
movswl %ax,%edi
movswl -0x4(%rbp),%esi
call   1030 <get_low_level_shape_definition@plt>
mov    %rax,-0x10(%rbp)
mov    -0x10(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<extended_get_shape_information>:
push   %rbp
push   %rbx
push   %rax
mov    %esi,%ebx
mov    %edi,%ebp
and    $0x1f,%ebp
mov    %ebp,%edi
call   1040 <get_collection_definition@plt>
mov    %ebp,%edi
mov    %ebx,%esi
add    $0x8,%rsp
pop    %rbx
pop    %rbp
jmp    1030 <get_low_level_shape_definition@plt>

LLVM IR (-O0):
%struct.shape_information_data = type { i32 }
%struct.low_level_shape_definition = type { i32 }
%struct.collection_definition = type { i32 }
define %struct.shape_information_data* @extended_get_shape_information(i16 signext %0, i16 signext %1) {
%3 = alloca i16
%4 = alloca i16
%5 = alloca i16
%6 = alloca %struct.low_level_shape_definition*
%7 = alloca %struct.collection_definition*
store i16 %0, i16* %3
store i16 %1, i16* %4
%8 = load i16, i16* %3
%9 = sext i16 %8 to i32
%10 = and i32 %9, 31
%11 = trunc i32 %10 to i16
store i16 %11, i16* %5
%12 = load i16, i16* %5
%13 = call %struct.collection_definition* @get_collection_definition(i16 signext %12)
store %struct.collection_definition* %13, %struct.collection_definition** %7
%14 = load i16, i16* %5
%15 = load i16, i16* %4
%16 = call %struct.low_level_shape_definition* @get_low_level_shape_definition(i16 signext %14, i16 signext %15)
store %struct.low_level_shape_definition* %16, %struct.low_level_shape_definition** %6
%17 = load %struct.low_level_shape_definition*, %struct.low_level_shape_definition** %6
%18 = bitcast %struct.low_level_shape_definition* %17 to %struct.shape_information_data*
ret %struct.shape_information_data* %18
}

LLVM IR (-O2):
%struct.shape_information_data = type { i32 }
%struct.collection_definition = type { i32 }
%struct.low_level_shape_definition = type { i32 }
define %struct.shape_information_data* @extended_get_shape_information(i16 signext %0, i16 signext %1) {
%3 = and i16 %0, 31
%4 = tail call %struct.collection_definition* @get_collection_definition(i16 signext %3)
%5 = tail call %struct.low_level_shape_definition* @get_low_level_shape_definition(i16 signext %3, i16 signext %1)
%6 = bitcast %struct.low_level_shape_definition* %5 to %struct.shape_information_data*
ret %struct.shape_information_data* %6
}