rendered paste body--- original_noise_math.h+++ noise_math_optimized.h@@ -1490,73 +1490,87 @@ return f; } +/* Unsigned arithmetic preserves the Java long wraparound. */+static inline __attribute__((const, always_inline)) uint64_t+noiseopt_biome_hash_step(uint64_t v, uint64_t salt) {+ return v * (v * UINT64_C(6364136223846793005) ++ UINT64_C(1442695040888963407)) + salt;+}++/* This comparison idiom maps to hardware MINPD for non-NaN inputs. */+static inline __attribute__((const, always_inline)) double+noiseopt_biome_min(double a, double b) {+ return a > b ? b : a;+}+ __attribute__((const)) uint32_t math_biome_access_sample(const int64_t theSeed, const int32_t x, const int32_t y, const int32_t z) {- const int32_t var0 = x - 2;- const int32_t var1 = y - 2;- const int32_t var2 = z - 2;- const int32_t var3 = var0 >> 2;- const int32_t var4 = var1 >> 2;- const int32_t var5 = var2 >> 2;- const double var6 = (double) (var0 & 3) / 4.0;- const double var7 = (double) (var1 & 3) / 4.0;- const double var8 = (double) (var2 & 3) / 4.0;- uint32_t var9 = 0;- double var10 = DBL_MAX;+ /* Java integer subtraction wraps modulo 2^32. */+ const int32_t xx = (int32_t)((uint32_t)x - 2u);+ const int32_t yy = (int32_t)((uint32_t)y - 2u);+ const int32_t zz = (int32_t)((uint32_t)z - 2u);++ const int32_t cx = xx >> 2;+ const int32_t cy = yy >> 2;+ const int32_t cz = zz >> 2;+ const double fx = (double)(xx & 3) * 0.25;+ const double fy = (double)(yy & 3) * 0.25;+ const double fz = (double)(zz & 3) * 0.25;++ const uint64_t seed = (uint64_t)theSeed;+ const uint64_t x0 = (uint64_t)(int64_t)cx;+ const uint64_t x1 = (uint64_t)(int64_t)(cx + 1);+ const uint64_t y0 = (uint64_t)(int64_t)cy;+ const uint64_t y1 = (uint64_t)(int64_t)(cy + 1);+ const uint64_t z0 = (uint64_t)(int64_t)cz;+ const uint64_t z1 = (uint64_t)(int64_t)(cz + 1); - double var28s[8]; ++ double distance[8]; #pragma clang loop vectorize_width(NOISEOPT_DOUBLE_LANES) interleave_count(NOISEOPT_BIOME_INTERLEAVE)- for (uint32_t var11 = 0; var11 < 8; ++var11) {- uint32_t var12 = var11 & 4;- uint32_t var13 = var11 & 2;- uint32_t var14 = var11 & 1;- int64_t var15 = var12 ? var3 + 1 : var3;- int64_t var16 = var13 ? var4 + 1 : var4;- int64_t var17 = var14 ? var5 + 1 : var5;- double var18 = var12 ? var6 - 1.0 : var6;- double var19 = var13 ? var7 - 1.0 : var7;- double var20 = var14 ? var8 - 1.0 : var8;- int64_t var21 = theSeed * (theSeed * 6364136223846793005L + 1442695040888963407L) + var15;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var15;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var16;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + var17;- double var22 = (double) ((var21 >> 24) & 1023) / 1024.0;- double var23 = (var22 - 0.5) * 0.9;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + theSeed;- double var24 = (double) ((var21 >> 24) & 1023) / 1024.0;- double var25 = (var24 - 0.5) * 0.9;- var21 = var21 * (var21 * 6364136223846793005L + 1442695040888963407L) + theSeed;- double var26 = (double) ((var21 >> 24) & 1023) / 1024.0;- double var27 = (var26 - 0.5) * 0.9;- double var28 = math_square(var20 + var27) + math_square(var19 + var25) + math_square(var18 + var23);- __builtin_assume(!__builtin_isnan(var28) && !__builtin_signbit(var28));- var28s[var11] = var28;+ for (uint32_t i = 0; i < 8; ++i) {+ const uint64_t ix = (i & 4) ? x1 : x0;+ const uint64_t iy = (i & 2) ? y1 : y0;+ const uint64_t iz = (i & 1) ? z1 : z0;+ const double dx = (i & 4) ? fx - 1.0 : fx;+ const double dy = (i & 2) ? fy - 1.0 : fy;+ const double dz = (i & 1) ? fz - 1.0 : fz;++ uint64_t h = noiseopt_biome_hash_step(noiseopt_biome_hash_step(seed, ix), iy);+ h = noiseopt_biome_hash_step(h, iz);+ h = noiseopt_biome_hash_step(h, ix);+ h = noiseopt_biome_hash_step(h, iy);+ h = noiseopt_biome_hash_step(h, iz);++ const double rx = ((double)((h >> 24) & 1023u) / 1024.0 - 0.5) * 0.9;+ h = noiseopt_biome_hash_step(h, seed);+ const double ry = ((double)((h >> 24) & 1023u) / 1024.0 - 0.5) * 0.9;+ h = noiseopt_biome_hash_step(h, seed);+ const double rz = ((double)((h >> 24) & 1023u) / 1024.0 - 0.5) * 0.9;++ distance[i] = math_square(dz + rz) + math_square(dy + ry) + math_square(dx + rx); } - // use bmin or use >= produces different asm- double m04 = __builtin_fmin(var28s[0], var28s[4]);- double m15 = __builtin_fmin(var28s[1], var28s[5]);- double m26 = __builtin_fmin(var28s[2], var28s[6]);- double m37 = __builtin_fmin(var28s[3], var28s[7]);- double m0426 = __builtin_fmin(m04, m26);- double m1537 = __builtin_fmin(m15, m37);- double minimum = __builtin_fmin(m0426, m1537);-- uint8_t bitmap = (uint8_t)(var28s[0] == minimum)- | (uint8_t)((var28s[1] == minimum) << 1)- | (uint8_t)((var28s[2] == minimum) << 2)- | (uint8_t)((var28s[3] == minimum) << 3)- | (uint8_t)((var28s[4] == minimum) << 4)- | (uint8_t)((var28s[5] == minimum) << 5)- | (uint8_t)((var28s[6] == minimum) << 6)- | (uint8_t)((var28s[7] == minimum) << 7);- - return __builtin_ctz(bitmap);+ const double m04 = noiseopt_biome_min(distance[0], distance[4]);+ const double m15 = noiseopt_biome_min(distance[1], distance[5]);+ const double m26 = noiseopt_biome_min(distance[2], distance[6]);+ const double m37 = noiseopt_biome_min(distance[3], distance[7]);+ const double m0426 = noiseopt_biome_min(m04, m26);+ const double m1537 = noiseopt_biome_min(m15, m37);+ const double minimum = noiseopt_biome_min(m0426, m1537);++ /* Distances are finite and >= +0.0, so at least one lane matches. */+ const unsigned mask = ((unsigned)(distance[0] == minimum) << 0)+ | ((unsigned)(distance[1] == minimum) << 1)+ | ((unsigned)(distance[2] == minimum) << 2)+ | ((unsigned)(distance[3] == minimum) << 3)+ | ((unsigned)(distance[4] == minimum) << 4)+ | ((unsigned)(distance[5] == minimum) << 5)+ | ((unsigned)(distance[6] == minimum) << 6)+ | ((unsigned)(distance[7] == minimum) << 7);+ return (uint32_t)__builtin_ctz(mask); }- typedef const struct aquifer_data { int32_t startX; int32_t startY;