float noise_grad4(int hash, float x, float y, float z, float t) {
  int h = hash & 31;
  float u = h < 24 ? x : y;
  float v = h < 16 ? y : z;
  float w = h < 8 ? z : t;
  return ((h & 1) ? -u : u) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w);
}


x86 assembly (clang, -O0):
<noise_grad4>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
movss  %xmm0,-0x8(%rbp)
movss  %xmm1,-0xc(%rbp)
movss  %xmm2,-0x10(%rbp)
movss  %xmm3,-0x14(%rbp)
mov    -0x4(%rbp),%eax
and    $0x1f,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x18,-0x18(%rbp)
jge    113d <noise_grad4+0x3d>
movss  -0x8(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
jmp    1147 <noise_grad4+0x47>
movss  -0xc(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
movss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x1c(%rbp)
cmpl   $0x10,-0x18(%rbp)
jge    116a <noise_grad4+0x6a>
movss  -0xc(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
jmp    1174 <noise_grad4+0x74>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
movss  -0x2c(%rbp),%xmm0
movss  %xmm0,-0x20(%rbp)
cmpl   $0x8,-0x18(%rbp)
jge    1197 <noise_grad4+0x97>
movss  -0x10(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
jmp    11a1 <noise_grad4+0xa1>
movss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     11d6 <noise_grad4+0xd6>
movss  -0x1c(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x34(%rbp)
jmp    11e0 <noise_grad4+0xe0>
movss  -0x1c(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x38(%rbp)
mov    -0x18(%rbp),%eax
and    $0x2,%eax
cmp    $0x0,%eax
je     1215 <noise_grad4+0x115>
movss  -0x20(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x3c(%rbp)
jmp    121f <noise_grad4+0x11f>
movss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x3c(%rbp)
movss  -0x38(%rbp),%xmm0
movss  -0x3c(%rbp),%xmm1
addss  %xmm1,%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x18(%rbp),%eax
and    $0x4,%eax
cmp    $0x0,%eax
je     125d <noise_grad4+0x15d>
movss  -0x24(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
movss  %xmm0,-0x44(%rbp)
jmp    1267 <noise_grad4+0x167>
movss  -0x24(%rbp),%xmm0
movss  %xmm0,-0x44(%rbp)
movss  -0x40(%rbp),%xmm0
movss  -0x44(%rbp),%xmm1
addss  %xmm1,%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<noise_grad4>:
mov    %edi,%eax
and    $0x1f,%eax
cmp    $0x18,%eax
jae    1142 <noise_grad4+0x42>
cmp    $0x10,%eax
jae    114a <noise_grad4+0x4a>
cmp    $0x8,%eax
jb     1117 <noise_grad4+0x17>
movaps %xmm3,%xmm2
movaps 0xee2(%rip),%xmm3
test   $0x1,%dil
je     1127 <noise_grad4+0x27>
xorps  %xmm3,%xmm0
test   $0x2,%dil
je     1130 <noise_grad4+0x30>
xorps  %xmm3,%xmm1
addss  %xmm1,%xmm0
test   $0x4,%dil
je     113d <noise_grad4+0x3d>
xorps  %xmm3,%xmm2
addss  %xmm2,%xmm0
ret
movaps %xmm1,%xmm0
cmp    $0x10,%eax
jb     110f <noise_grad4+0xf>
movaps %xmm2,%xmm1
cmp    $0x8,%eax
jae    1114 <noise_grad4+0x14>
jmp    1117 <noise_grad4+0x17>

LLVM IR (-O0):
define float @noise_grad4(i32 %0, float %1, float %2, float %3, float %4) {
%6 = alloca i32
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca float
%11 = alloca i32
%12 = alloca float
%13 = alloca float
%14 = alloca float
store i32 %0, i32* %6
store float %1, float* %7
store float %2, float* %8
store float %3, float* %9
store float %4, float* %10
%15 = load i32, i32* %6
%16 = and i32 %15, 31
store i32 %16, i32* %11
%17 = load i32, i32* %11
%18 = icmp slt i32 %17, 24
br i1 %18, label %19, label %21
19: ; preds = %5
%20 = load float, float* %7
br label %23
21: ; preds = %5
%22 = load float, float* %8
br label %23
23: ; preds = %21, %19
%24 = phi float [ %20, %19 ], [ %22, %21 ]
store float %24, float* %12
%25 = load i32, i32* %11
%26 = icmp slt i32 %25, 16
br i1 %26, label %27, label %29
27: ; preds = %23
%28 = load float, float* %8
br label %31
29: ; preds = %23
%30 = load float, float* %9
br label %31
31: ; preds = %29, %27
%32 = phi float [ %28, %27 ], [ %30, %29 ]
store float %32, float* %13
%33 = load i32, i32* %11
%34 = icmp slt i32 %33, 8
br i1 %34, label %35, label %37
35: ; preds = %31
%36 = load float, float* %9
br label %39
37: ; preds = %31
%38 = load float, float* %10
br label %39
39: ; preds = %37, %35
%40 = phi float [ %36, %35 ], [ %38, %37 ]
store float %40, float* %14
%41 = load i32, i32* %11
%42 = and i32 %41, 1
%43 = icmp ne i32 %42, 0
br i1 %43, label %44, label %47
44: ; preds = %39
%45 = load float, float* %12
%46 = fneg float %45
br label %49
47: ; preds = %39
%48 = load float, float* %12
br label %49
49: ; preds = %47, %44
%50 = phi float [ %46, %44 ], [ %48, %47 ]
%51 = load i32, i32* %11
%52 = and i32 %51, 2
%53 = icmp ne i32 %52, 0
br i1 %53, label %54, label %57
54: ; preds = %49
%55 = load float, float* %13
%56 = fneg float %55
br label %59
57: ; preds = %49
%58 = load float, float* %13
br label %59
59: ; preds = %57, %54
%60 = phi float [ %56, %54 ], [ %58, %57 ]
%61 = fadd float %50, %60
%62 = load i32, i32* %11
%63 = and i32 %62, 4
%64 = icmp ne i32 %63, 0
br i1 %64, label %65, label %68
65: ; preds = %59
%66 = load float, float* %14
%67 = fneg float %66
br label %70
68: ; preds = %59
%69 = load float, float* %14
br label %70
70: ; preds = %68, %65
%71 = phi float [ %67, %65 ], [ %69, %68 ]
%72 = fadd float %61, %71
ret float %72
}

LLVM IR (-O2):
define float @noise_grad4(i32 %0, float %1, float %2, float %3, float %4) {
%6 = and i32 %0, 31
%7 = icmp ult i32 %6, 24
%8 = select i1 %7, float %1, float %2
%9 = icmp ult i32 %6, 16
%10 = select i1 %9, float %2, float %3
%11 = icmp ult i32 %6, 8
%12 = select i1 %11, float %3, float %4
%13 = and i32 %0, 1
%14 = icmp eq i32 %13, 0
%15 = fneg float %8
%16 = select i1 %14, float %8, float %15
%17 = and i32 %0, 2
%18 = icmp eq i32 %17, 0
%19 = fneg float %10
%20 = select i1 %18, float %10, float %19
%21 = fadd float %16, %20
%22 = and i32 %0, 4
%23 = icmp eq i32 %22, 0
%24 = fneg float %12
%25 = select i1 %23, float %12, float %24
%26 = fadd float %21, %25
ret float %26
}