#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 typeExp {
  int dummy;
};

/* Variables and functions */
struct typeExp *CreateType(int, char *, struct typeExp *, struct typeExp *);
struct typeExp *PairType(void) {
  return (CreateType(
      7, "a",
      CreateType(
          7, "b",
          CreateType(4, "", CreateType(3, "a", 0, 0),
                     CreateType(4, "", CreateType(3, "b", 0, 0),
                                CreateType(5, "", CreateType(3, "a", 0, 0),
                                           CreateType(3, "b", 0, 0)))),
          0),
      0));
}


x86 assembly (clang, -O0):
<PairType>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    $0x3,%edi
lea    0xedc(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   1030 <CreateType@plt>
mov    %rax,-0x8(%rbp)
mov    $0x3,%edi
lea    0xec2(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   1030 <CreateType@plt>
mov    %rax,-0x10(%rbp)
mov    $0x3,%edi
lea    0xea4(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   1030 <CreateType@plt>
mov    %rax,-0x18(%rbp)
mov    $0x3,%edi
lea    0xe8a(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
mov    %rcx,%rdx
call   1030 <CreateType@plt>
mov    -0x18(%rbp),%rdx
mov    %rax,%rcx
mov    $0x5,%edi
lea    0xe6a(%rip),%rsi
call   1030 <CreateType@plt>
mov    -0x10(%rbp),%rdx
mov    %rax,%rcx
mov    $0x4,%edi
lea    0xe52(%rip),%rsi
call   1030 <CreateType@plt>
mov    -0x8(%rbp),%rdx
mov    %rax,%rcx
mov    $0x4,%edi
lea    0xe3a(%rip),%rsi
call   1030 <CreateType@plt>
mov    %rax,%rdx
mov    $0x7,%edi
lea    0xe27(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
call   1030 <CreateType@plt>
mov    %rax,%rdx
mov    $0x7,%edi
lea    0xe0d(%rip),%rsi
xor    %eax,%eax
mov    %eax,%ecx
call   1030 <CreateType@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<PairType>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
lea    0xede(%rip),%r14
mov    $0x3,%edi
mov    %r14,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
call   1030 <CreateType@plt>
mov    %rax,%r12
lea    0xec5(%rip),%r15
mov    $0x3,%edi
mov    %r15,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
call   1030 <CreateType@plt>
mov    %rax,%r13
mov    $0x3,%edi
mov    %r14,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
call   1030 <CreateType@plt>
mov    %rax,%rbx
mov    $0x3,%edi
mov    %r15,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
call   1030 <CreateType@plt>
lea    0xe84(%rip),%rbp
mov    $0x5,%edi
mov    %rbp,%rsi
mov    %rbx,%rdx
mov    %rax,%rcx
call   1030 <CreateType@plt>
mov    $0x4,%edi
mov    %rbp,%rsi
mov    %r13,%rdx
mov    %rax,%rcx
call   1030 <CreateType@plt>
mov    $0x4,%edi
mov    %rbp,%rsi
mov    %r12,%rdx
mov    %rax,%rcx
call   1030 <CreateType@plt>
mov    $0x7,%edi
mov    %r15,%rsi
mov    %rax,%rdx
xor    %ecx,%ecx
call   1030 <CreateType@plt>
mov    $0x7,%edi
mov    %r14,%rsi
mov    %rax,%rdx
xor    %ecx,%ecx
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <CreateType@plt>

LLVM IR (-O0):
%struct.typeExp = type { i32 }
@.str = [2 x i8] c"a\00"
@.str.1 = [2 x i8] c"b\00"
@.str.2 = [1 x i8] zeroinitializer
define %struct.typeExp* @PairType() {
%1 = call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%2 = call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%3 = call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%4 = call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%5 = call %struct.typeExp* @CreateType(i32 5, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %3, %struct.typeExp* %4)
%6 = call %struct.typeExp* @CreateType(i32 4, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %2, %struct.typeExp* %5)
%7 = call %struct.typeExp* @CreateType(i32 4, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %1, %struct.typeExp* %6)
%8 = call %struct.typeExp* @CreateType(i32 7, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* %7, %struct.typeExp* null)
%9 = call %struct.typeExp* @CreateType(i32 7, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* %8, %struct.typeExp* null)
ret %struct.typeExp* %9
}

LLVM IR (-O2):
%struct.typeExp = type { i32 }
@.str = [2 x i8] c"a\00"
@.str.1 = [2 x i8] c"b\00"
@.str.2 = [1 x i8] zeroinitializer
define %struct.typeExp* @PairType() {
%1 = tail call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%2 = tail call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%3 = tail call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%4 = tail call %struct.typeExp* @CreateType(i32 3, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* null, %struct.typeExp* null)
%5 = tail call %struct.typeExp* @CreateType(i32 5, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %3, %struct.typeExp* %4)
%6 = tail call %struct.typeExp* @CreateType(i32 4, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %2, %struct.typeExp* %5)
%7 = tail call %struct.typeExp* @CreateType(i32 4, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.2, i64 0, i64 0), %struct.typeExp* %1, %struct.typeExp* %6)
%8 = tail call %struct.typeExp* @CreateType(i32 7, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i64 0, i64 0), %struct.typeExp* %7, %struct.typeExp* null)
%9 = tail call %struct.typeExp* @CreateType(i32 7, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0), %struct.typeExp* %8, %struct.typeExp* null)
ret %struct.typeExp* %9
}