void quarticgrad(double *x, int N, double *g) {
  double t1, t2, t3, t4;
  t1 = (x[0] + 10 * x[1]);
  t2 = (x[2] - x[3]);
  t3 = (x[1] - 2 * x[2]);
  t4 = (x[0] - x[3]);
  g[0] = 2 * t1 + 40 * t4 * t4 * t4;
  g[1] = 20 * t1 + 4 * t3 * t3 * t3;
  g[2] = 10 * t2 - 8 * t3 * t3 * t3;
  g[3] = -10 * t2 - 40 * t4 * t4 * t4;
}


x86 assembly (clang, -O0):
<quarticgrad>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm1
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  0xee8(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x8(%rbp),%rax
subsd  0x18(%rax),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm1
addsd  %xmm1,%xmm1
subsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
mov    -0x8(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x8(%rbp),%rax
subsd  0x18(%rax),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xe7a(%rip),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
addsd  %xmm0,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x20(%rbp),%xmm0
movsd  0xe6e(%rip),%xmm1
mulsd  -0x30(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movsd  0xe4f(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movsd  -0x28(%rbp),%xmm0
movsd  0xe29(%rip),%xmm1
mulsd  -0x30(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  0xdf3(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x10(%rax)
movsd  -0x28(%rbp),%xmm0
movsd  0xdcd(%rip),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
mulsd  -0x38(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
movsd  0xd97(%rip),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x18(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<quarticgrad>:
movsd  (%rdi),%xmm2
movsd  0x8(%rdi),%xmm1
movsd  0xeef(%rip),%xmm3
mulsd  %xmm1,%xmm3
addsd  %xmm2,%xmm3
movsd  0x10(%rdi),%xmm4
movsd  0x18(%rdi),%xmm5
movapd %xmm4,%xmm0
subsd  %xmm5,%xmm0
addsd  %xmm4,%xmm4
subsd  %xmm4,%xmm1
subsd  %xmm5,%xmm2
unpcklpd %xmm1,%xmm2
movapd 0xecd(%rip),%xmm4
mulpd  %xmm2,%xmm4
mulpd  %xmm2,%xmm4
mulpd  %xmm2,%xmm4
unpcklpd %xmm3,%xmm3
mulpd  0xec5(%rip),%xmm3
addpd  %xmm4,%xmm3
movupd %xmm3,(%rdx)
movsd  0xe9d(%rip),%xmm2
mulsd  %xmm1,%xmm2
mulsd  %xmm1,%xmm2
mulsd  %xmm1,%xmm2
xorpd  0xeb1(%rip),%xmm4
unpcklpd %xmm4,%xmm2
unpcklpd %xmm0,%xmm0
mulpd  0xeb1(%rip),%xmm0
addpd  %xmm2,%xmm0
movupd %xmm0,0x10(%rdx)
ret

LLVM IR (-O0):
define void @quarticgrad(double* %0, i32 %1, double* %2) {
%4 = alloca double*
%5 = alloca i32
%6 = alloca double*
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
store double* %0, double** %4
store i32 %1, i32* %5
store double* %2, double** %6
%11 = load double*, double** %4
%12 = getelementptr inbounds double, double* %11, i64 0
%13 = load double, double* %12
%14 = load double*, double** %4
%15 = getelementptr inbounds double, double* %14, i64 1
%16 = load double, double* %15
%17 = call double @llvm.fmuladd.f64(double 1.000000e+01, double %16, double %13)
store double %17, double* %7
%18 = load double*, double** %4
%19 = getelementptr inbounds double, double* %18, i64 2
%20 = load double, double* %19
%21 = load double*, double** %4
%22 = getelementptr inbounds double, double* %21, i64 3
%23 = load double, double* %22
%24 = fsub double %20, %23
store double %24, double* %8
%25 = load double*, double** %4
%26 = getelementptr inbounds double, double* %25, i64 1
%27 = load double, double* %26
%28 = load double*, double** %4
%29 = getelementptr inbounds double, double* %28, i64 2
%30 = load double, double* %29
%31 = call double @llvm.fmuladd.f64(double -2.000000e+00, double %30, double %27)
store double %31, double* %9
%32 = load double*, double** %4
%33 = getelementptr inbounds double, double* %32, i64 0
%34 = load double, double* %33
%35 = load double*, double** %4
%36 = getelementptr inbounds double, double* %35, i64 3
%37 = load double, double* %36
%38 = fsub double %34, %37
store double %38, double* %10
%39 = load double, double* %7
%40 = load double, double* %10
%41 = fmul double 4.000000e+01, %40
%42 = load double, double* %10
%43 = fmul double %41, %42
%44 = load double, double* %10
%45 = fmul double %43, %44
%46 = call double @llvm.fmuladd.f64(double 2.000000e+00, double %39, double %45)
%47 = load double*, double** %6
%48 = getelementptr inbounds double, double* %47, i64 0
store double %46, double* %48
%49 = load double, double* %7
%50 = load double, double* %9
%51 = fmul double 4.000000e+00, %50
%52 = load double, double* %9
%53 = fmul double %51, %52
%54 = load double, double* %9
%55 = fmul double %53, %54
%56 = call double @llvm.fmuladd.f64(double 2.000000e+01, double %49, double %55)
%57 = load double*, double** %6
%58 = getelementptr inbounds double, double* %57, i64 1
store double %56, double* %58
%59 = load double, double* %8
%60 = load double, double* %9
%61 = fmul double 8.000000e+00, %60
%62 = load double, double* %9
%63 = fmul double %61, %62
%64 = load double, double* %9
%65 = fmul double %63, %64
%66 = fneg double %65
%67 = call double @llvm.fmuladd.f64(double 1.000000e+01, double %59, double %66)
%68 = load double*, double** %6
%69 = getelementptr inbounds double, double* %68, i64 2
store double %67, double* %69
%70 = load double, double* %8
%71 = load double, double* %10
%72 = fmul double 4.000000e+01, %71
%73 = load double, double* %10
%74 = fmul double %72, %73
%75 = load double, double* %10
%76 = fmul double %74, %75
%77 = fneg double %76
%78 = call double @llvm.fmuladd.f64(double -1.000000e+01, double %70, double %77)
%79 = load double*, double** %6
%80 = getelementptr inbounds double, double* %79, i64 3
store double %78, double* %80
ret void
}

LLVM IR (-O2):
define void @quarticgrad(double* nocapture %0, i32 %1, double* nocapture writeonly %2) {
%4 = load double, double* %0
%5 = getelementptr inbounds double, double* %0, i64 1
%6 = load double, double* %5
%7 = tail call double @llvm.fmuladd.f64(double %6, double 1.000000e+01, double %4)
%8 = getelementptr inbounds double, double* %0, i64 2
%9 = load double, double* %8
%10 = getelementptr inbounds double, double* %0, i64 3
%11 = load double, double* %10
%12 = fsub double %9, %11
%13 = tail call double @llvm.fmuladd.f64(double %9, double -2.000000e+00, double %6)
%14 = fsub double %4, %11
%15 = insertelement <2 x double> poison, double %14, i64 0
%16 = insertelement <2 x double> %15, double %13, i64 1
%17 = fmul <2 x double> %16, <double 4.000000e+01, double 4.000000e+00>
%18 = fmul <2 x double> %16, %17
%19 = fmul <2 x double> %16, %18
%20 = insertelement <2 x double> poison, double %7, i64 0
%21 = shufflevector <2 x double> %20, <2 x double> poison, <2 x i32> zeroinitializer
%22 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %21, <2 x double> <double 2.000000e+00, double 2.000000e+01>, <2 x double> %19)
%23 = bitcast double* %2 to <2 x double>*
store <2 x double> %22, <2 x double>* %23
%24 = fmul double %13, -8.000000e+00
%25 = fmul double %13, %24
%26 = fmul double %13, %25
%27 = getelementptr inbounds double, double* %2, i64 2
%28 = extractelement <2 x double> %19, i64 0
%29 = fneg double %28
%30 = insertelement <2 x double> poison, double %12, i64 0
%31 = shufflevector <2 x double> %30, <2 x double> poison, <2 x i32> zeroinitializer
%32 = insertelement <2 x double> poison, double %26, i64 0
%33 = insertelement <2 x double> %32, double %29, i64 1
%34 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %31, <2 x double> <double 1.000000e+01, double -1.000000e+01>, <2 x double> %33)
%35 = bitcast double* %27 to <2 x double>*
store <2 x double> %34, <2 x double>* %35
ret void
}