#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 */
typedef short uint64_t;

/* Variables and functions */
void set_bits(short lobit, short hibit, uint64_t value, uint64_t *mask) {
  short num_bits = hibit - lobit + 1;
  uint64_t ones_mask = (1ll << (num_bits)) - 1;
  *mask &= ~(ones_mask << lobit);
  *mask |= value << lobit;
}


x86 assembly (clang, -O0):
<set_bits>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %si,%dx
mov    %di,%si
mov    %si,-0x2(%rbp)
mov    %dx,-0x4(%rbp)
mov    %ax,-0x6(%rbp)
mov    %rcx,-0x10(%rbp)
movswl -0x4(%rbp),%eax
movswl -0x2(%rbp),%ecx
sub    %ecx,%eax
add    $0x1,%eax
mov    %ax,-0x12(%rbp)
movswl -0x12(%rbp),%eax
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x1,%eax
shl    %cl,%rax
sub    $0x1,%rax
mov    %ax,-0x14(%rbp)
movswl -0x14(%rbp),%edx
movswl -0x2(%rbp),%ecx
shl    %cl,%edx
xor    $0xffffffff,%edx
mov    -0x10(%rbp),%rax
movswl (%rax),%ecx
and    %edx,%ecx
mov    %cx,(%rax)
movswl -0x6(%rbp),%edx
movswl -0x2(%rbp),%ecx
shl    %cl,%edx
mov    -0x10(%rbp),%rax
movswl (%rax),%ecx
or     %edx,%ecx
mov    %cx,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<set_bits>:
mov    %rcx,%rax
sub    %edi,%esi
lea    0x1(%rsi),%ecx
mov    $0xffffffffffffffff,%rsi
shl    %cl,%rsi
not    %esi
mov    %edi,%ecx
shl    %cl,%esi
not    %esi
movzwl %dx,%edx
shl    %cl,%edx
and    (%rax),%si
or     %esi,%edx
mov    %dx,(%rax)
ret

LLVM IR (-O0):
define void @set_bits(i16 signext %0, i16 signext %1, i16 signext %2, i16* %3) {
%5 = alloca i16
%6 = alloca i16
%7 = alloca i16
%8 = alloca i16*
%9 = alloca i16
%10 = alloca i16
store i16 %0, i16* %5
store i16 %1, i16* %6
store i16 %2, i16* %7
store i16* %3, i16** %8
%11 = load i16, i16* %6
%12 = sext i16 %11 to i32
%13 = load i16, i16* %5
%14 = sext i16 %13 to i32
%15 = sub nsw i32 %12, %14
%16 = add nsw i32 %15, 1
%17 = trunc i32 %16 to i16
store i16 %17, i16* %9
%18 = load i16, i16* %9
%19 = sext i16 %18 to i32
%20 = zext i32 %19 to i64
%21 = shl i64 1, %20
%22 = sub nsw i64 %21, 1
%23 = trunc i64 %22 to i16
store i16 %23, i16* %10
%24 = load i16, i16* %10
%25 = sext i16 %24 to i32
%26 = load i16, i16* %5
%27 = sext i16 %26 to i32
%28 = shl i32 %25, %27
%29 = xor i32 %28, -1
%30 = load i16*, i16** %8
%31 = load i16, i16* %30
%32 = sext i16 %31 to i32
%33 = and i32 %32, %29
%34 = trunc i32 %33 to i16
store i16 %34, i16* %30
%35 = load i16, i16* %7
%36 = sext i16 %35 to i32
%37 = load i16, i16* %5
%38 = sext i16 %37 to i32
%39 = shl i32 %36, %38
%40 = load i16*, i16** %8
%41 = load i16, i16* %40
%42 = sext i16 %41 to i32
%43 = or i32 %42, %39
%44 = trunc i32 %43 to i16
store i16 %44, i16* %40
ret void
}

LLVM IR (-O2):
define void @set_bits(i16 signext %0, i16 signext %1, i16 signext %2, i16* nocapture %3) {
%5 = sext i16 %0 to i32
%6 = sub i16 1, %0
%7 = add i16 %6, %1
%8 = sext i16 %7 to i64
%9 = and i64 %8, 4294967295
%10 = shl nsw i64 -1, %9
%11 = trunc i64 %10 to i32
%12 = xor i32 %11, -1
%13 = shl i32 %12, %5
%14 = load i16, i16* %3
%15 = trunc i32 %13 to i16
%16 = xor i16 %15, -1
%17 = and i16 %14, %16
%18 = zext i16 %2 to i32
%19 = shl i32 %18, %5
%20 = trunc i32 %19 to i16
%21 = or i16 %17, %20
store i16 %21, i16* %3
ret void
}