Unbreak build of llvmpipe with LLVM 7 on PowerPC (mesa 26.2.0)

Rebased from the 26.2-devel version of this patch onto the 26.2.0 release.

Combines five things:

1. A targeted revert of the LLVM-7-relevant parts of
   https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35374
   ("meson: Require LLVM 8 or newer"):
   - meson floor back to LLVM >= 7
   - GALLIVM_COROUTINES: the llvm-c coroutine passes API only exists from
     LLVM 8, so compute/mesh/task and tessellation are disabled for LLVM 7
     (fragment/vertex/geometry do not use coroutines)
   - lp_bld_passmgr.c HAVE_CORO gating (llvm-c/Transforms/Coroutines.h does
     not exist in LLVM 7)
   - LLVMBuild{GEP2,InBoundsGEP2,Load2,Call2} wrappers for LLVM < 8
   - pre-LLVM-8 saturated add/sub paths (llvm.{s,u}{add,sub}.sat only exist
     from LLVM 8; uses SSE2/AltiVec intrinsics or generic clamping)

2. The previous patch-build-with-LLVM-7.diff, rebased: debug-info C API
   signature differences (LLVMDIBuilderCreateBasicType/CreateCompileUnit),
   LLVMSetCurrentDebugLocation2 (LLVM 9+), float atomics enum values
   (LLVM 9+/15+).

3. Guards needed for current mesa:
   - LLVMBuildFreeze wrapper (instruction only exists from LLVM 10;
     passes the value through unchanged)
   - lp_bld_type.h includes gallivm/lp_bld.h again (an upstream include
     cleanup replaced it with llvm-c/Core.h, which would leave the
     wrappers above invisible to most gallivm code); two files that do
     not reach that header include lp_bld.h directly

4. PowerPC target triples for the Apple MCJIT path in lp_bld_misc.cpp.
   Commit 9e24785f8156 ("llvmpipe: fix arch of LLVM JIT when cross
   compiling on Apple", 2026-07-07, new in 26.2.0) forces an explicit
   target triple under DETECT_OS_APPLE and #errors out on any arch it
   does not enumerate, which on Darwin/PPC is a hard build failure:

     lp_bld_misc.cpp:551:6: error: #error Unsupported architecture for
     MCJIT on Apple.

   Add the powerpc/powerpc64 cases. DETECT_ARCH_PPC_64 is tested first
   because detect_arch.h sets DETECT_ARCH_PPC for both. The macros reach
   this file via u_debug.h -> os_misc.h -> util/detect.h.
   (Upstream may prefer falling back to LLVM_HOST_TRIPLE instead of
   #error, which would cover every other non-enumerated architecture too.)

5. A GCC-safe fallback for __builtin_available() in src/glx/glxext.c.
   26.2.0 elects AppleGL at run time and uses __builtin_available() to skip
   that election on macOS 26.0-26.5 (XQuartz issue #446).  That is a clang
   builtin; GCC has no equivalent, so the file does not compile with
   gcc-mp-N:

     glxext.c:1056:18: error: implicit declaration of function
     '__builtin_available'

   Define GLX_BUILTIN_AVAILABLE() to the builtin when __has_builtin says it
   exists and to 1 otherwise.  A deployment target predating macOS 26 cannot
   hit the breakage being worked around, so "available" is the correct
   answer and reproduces the pre-existing behaviour of electing AppleGL.

Changes when rebasing 26.2-devel -> 26.2.0:

 - Dropped the src/gallium/auxiliary/gallivm/lp_bld_jit_types.c hunk.
   It guarded LLVMBuildIntCast2 (LLVM 8+) in lp_llvm_descriptor_base();
   both that function and every other use of LLVMBuildIntCast2 are gone
   from 26.2.0, so the guard has no call site left.
 - Re-anchored the src/gallium/auxiliary/gallivm/lp_bld.h hunk: upstream
   added a comment block ahead of "typedef struct lp_context_ref", which
   was this hunk's trailing context.
 - Added the lp_bld_misc.cpp hunk described in 4 above.
 - lp_bld_nir_soa.c: the debug-location guard now also covers the
   di_loc/debug_info declarations, which are otherwise unused (and warn)
   when LLVM < 9.
 - Added the src/glx/glxext.c hunk described in 5 above.

Note that 26.2.0 dropped GLX_USE_APPLE entirely: meson now defines only
GLX_USE_APPLEGL, drisw_glx.c is gated on GLX_DIRECT_RENDERING alone, and the
AppleGL-vs-gallium decision moved into __glXInitialize() at run time
(suppressed by GALLIUM_DRIVER, overridable with MESA_LOADER_DRIVER_OVERRIDE).
The old build-time heuristic keyed on the gallium driver count is gone, so
+llvm no longer decides whether libGL forwards to OpenGL.framework.

Re-audited every llvm-c identifier used under src/gallium/{auxiliary/gallivm,
auxiliary/draw,drivers/llvmpipe} in 26.2.0 against the LLVM 7.1 llvm-c
headers. Everything absent from LLVM 7 is either handled here or already
guarded upstream (LLVMAddInstructionSimplifyPass behind LLVM_VERSION_MAJOR
<= 11, LLVMDIBuilderInsertDeclareRecordAtEnd behind >= 19, LP_IMAGE_OP_COUNT
behind >= 15, and all LLVMOrc*/PassBuilder symbols behind GALLIVM_USE_ORCJIT,
which is 0 for ppc because meson lists ppc/ppc64 in llvm_has_mcjit).

diff --git meson.build meson.build
--- meson.build
+++ meson.build
@@ -1994,7 +1994,7 @@
 elif with_clc or llvm_with_orcjit
   _llvm_version = '>= 15.0.0'
 else
-  _llvm_version = '>= 8.0.0'
+  _llvm_version = '>= 7.0.0'
 endif
 
 _shared_llvm = get_option('shared-llvm') \
diff --git src/gallium/auxiliary/draw/draw_llvm.c src/gallium/auxiliary/draw/draw_llvm.c
--- src/gallium/auxiliary/draw/draw_llvm.c
+++ src/gallium/auxiliary/draw/draw_llvm.c
@@ -1718,8 +1718,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    memset(&vs_type, 0, sizeof vs_type);
@@ -2468,8 +2472,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    lp_build_context_init(&bld, gallivm, lp_type_int(32));
@@ -3056,8 +3064,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    lp_build_context_init(&bld, gallivm, lp_type_int(32));
@@ -3133,8 +3145,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    resources_ptr = LLVMGetParam(variant_coro, 0);
@@ -3655,8 +3671,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    lp_build_context_init(&bld, gallivm, lp_type_int(32));
diff --git src/gallium/auxiliary/gallivm/lp_bld.h src/gallium/auxiliary/gallivm/lp_bld.h
--- src/gallium/auxiliary/gallivm/lp_bld.h
+++ src/gallium/auxiliary/gallivm/lp_bld.h
@@ -90,6 +90,69 @@
 #define LLVMInsertBasicBlock ILLEGAL_LLVM_FUNCTION
 #define LLVMCreateBuilder ILLEGAL_LLVM_FUNCTION
 
+#if LLVM_VERSION_MAJOR >= 8
+#define GALLIVM_COROUTINES 1
+#else
+#define GALLIVM_COROUTINES 0
+#endif
+
+/* LLVM is transitioning to "opaque pointers", and as such deprecates
+ * LLVMBuildGEP, LLVMBuildCall, LLVMBuildLoad, replacing them with
+ * LLVMBuildGEP2, LLVMBuildCall2, LLVMBuildLoad2 respectivelly.
+ * These new functions were added in LLVM 8.0; so for LLVM before 8.0 we
+ * simply forward to the non-opaque-pointer variants.
+ */
+#if LLVM_VERSION_MAJOR < 8
+
+static inline LLVMValueRef
+LLVMBuildGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
+              LLVMValueRef Pointer, LLVMValueRef *Indices,
+              unsigned NumIndices, const char *Name)
+{
+   return LLVMBuildGEP(B, Pointer, Indices, NumIndices, Name);
+}
+
+static inline LLVMValueRef
+LLVMBuildInBoundsGEP2(LLVMBuilderRef B, LLVMTypeRef Ty,
+                      LLVMValueRef Pointer, LLVMValueRef *Indices,
+                      unsigned NumIndices, const char *Name)
+{
+   return LLVMBuildInBoundsGEP(B, Pointer, Indices, NumIndices, Name);
+}
+
+static inline LLVMValueRef
+LLVMBuildLoad2(LLVMBuilderRef B, LLVMTypeRef Ty,
+               LLVMValueRef PointerVal, const char *Name)
+{
+  LLVMValueRef val = LLVMBuildLoad(B, PointerVal, Name);
+  return LLVMTypeOf(val) == Ty ? val : LLVMBuildBitCast(B, val, Ty, Name);
+}
+
+static inline LLVMValueRef
+LLVMBuildCall2(LLVMBuilderRef B, LLVMTypeRef Ty, LLVMValueRef Fn,
+               LLVMValueRef *Args, unsigned NumArgs,
+               const char *Name)
+{
+   return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
+}
+
+#endif /* LLVM_VERSION_MAJOR < 8 */
+
+/* LLVMBuildFreeze was added in LLVM 10; earlier LLVM has no freeze
+ * instruction, so just pass the value through unchanged.
+ */
+#if LLVM_VERSION_MAJOR < 10
+
+static inline LLVMValueRef
+LLVMBuildFreeze(LLVMBuilderRef B, LLVMValueRef Val, const char *Name)
+{
+   (void)B;
+   (void)Name;
+   return Val;
+}
+
+#endif /* LLVM_VERSION_MAJOR < 10 */
+
 /* ORC's ThreadSafeContext only locks during add-to-JIT; IR building
  * touches the LLVMContext without that lock, so a separate mutex is
  * needed for shareable shaders. Aliasing copies (owned=false) share
diff --git src/gallium/auxiliary/gallivm/lp_bld_arit.c src/gallium/auxiliary/gallivm/lp_bld_arit.c
--- src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -427,10 +427,71 @@
         return bld->one;
 
       if (!type.floating && !type.fixed) {
+#if LLVM_VERSION_MAJOR >= 8
          char intrin[32];
          const char *intrinsic = type.sign ? "llvm.sadd.sat" : "llvm.uadd.sat";
          lp_format_intrinsic(intrin, sizeof intrin, intrinsic, bld->vec_type);
          return lp_build_intrinsic_binary(builder, intrin, bld->vec_type, a, b);
+#else
+         const char *intrinsic = NULL;
+         if (type.width * type.length == 128) {
+            if (util_get_cpu_caps()->has_sse2) {
+               if (type.width == 8)
+                 intrinsic = type.sign ? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b";
+               if (type.width == 16)
+                 intrinsic = type.sign ? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w";
+            } else if (util_get_cpu_caps()->has_altivec) {
+               if (type.width == 8)
+                  intrinsic = type.sign ? "llvm.ppc.altivec.vaddsbs" : "llvm.ppc.altivec.vaddubs";
+               if (type.width == 16)
+                  intrinsic = type.sign ? "llvm.ppc.altivec.vaddshs" : "llvm.ppc.altivec.vadduhs";
+            }
+         }
+         if (type.width * type.length == 256) {
+            if (util_get_cpu_caps()->has_avx2) {
+               if (type.width == 8)
+                  intrinsic = type.sign ? "llvm.x86.avx2.padds.b" : "llvm.x86.avx2.paddus.b";
+               if (type.width == 16)
+                  intrinsic = type.sign ? "llvm.x86.avx2.padds.w" : "llvm.x86.avx2.paddus.w";
+            }
+         }
+         if (intrinsic)
+            return lp_build_intrinsic_binary(builder, intrinsic,
+                          lp_build_vec_type(bld->gallivm, bld->type), a, b);
+
+         if (type.sign) {
+            uint64_t sign = (uint64_t)1 << (type.width - 1);
+            LLVMValueRef max_val = lp_build_const_int_vec(bld->gallivm, type, sign - 1);
+            LLVMValueRef min_val = lp_build_const_int_vec(bld->gallivm, type, sign);
+            /* a_clamp_max is the maximum a for positive b,
+               a_clamp_min is the minimum a for negative b. */
+            LLVMValueRef a_clamp_max =
+               lp_build_min_simple(bld, a, LLVMBuildSub(builder, max_val, b, ""),
+                                   GALLIVM_NAN_BEHAVIOR_UNDEFINED);
+            LLVMValueRef a_clamp_min =
+               lp_build_max_simple(bld, a, LLVMBuildSub(builder, min_val, b, ""),
+                                   GALLIVM_NAN_BEHAVIOR_UNDEFINED);
+            a = lp_build_select(bld, lp_build_cmp(bld, PIPE_FUNC_GREATER, b,
+                                        bld->zero), a_clamp_max, a_clamp_min);
+            return LLVMBuildAdd(builder, a, b, "");
+         } else {
+            /*
+             * newer llvm versions no longer support the intrinsics, but recognize
+             * the pattern. Since auto-upgrade of intrinsics doesn't work for jit
+             * code, it is important we match the pattern llvm uses (and pray llvm
+             * doesn't change it - and hope they decide on the same pattern for
+             * all backends supporting it...).
+             * NOTE: cmp/select does sext/trunc of the mask. Does not seem to
+             * interfere with llvm's ability to recognize the pattern but seems
+             * a bit brittle.
+             * NOTE: llvm 9+ always uses (non arch specific) intrinsic.
+             */
+            res = LLVMBuildAdd(builder, a, b, "");
+            LLVMValueRef overflowed = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, res);
+            return lp_build_select(bld, overflowed,
+                                   LLVMConstAllOnes(bld->int_vec_type), res);
+         }
+#endif
       }
    }
 
@@ -689,10 +750,34 @@
         return bld->zero;
 
       if (!type.floating && !type.fixed) {
+#if LLVM_VERSION_MAJOR >= 8
          char intrin[32];
          intrinsic = type.sign ? "llvm.ssub.sat" : "llvm.usub.sat";
          lp_format_intrinsic(intrin, sizeof intrin, intrinsic, bld->vec_type);
          return lp_build_intrinsic_binary(builder, intrin, bld->vec_type, a, b);
+#else
+         if (type.width * type.length == 128) {
+            if (util_get_cpu_caps()->has_sse2) {
+               if (type.width == 8)
+                  intrinsic = type.sign ? "llvm.x86.sse2.psubs.b" : "llvm.x86.sse2.psubus.b";
+               if (type.width == 16)
+                  intrinsic = type.sign ? "llvm.x86.sse2.psubs.w" : "llvm.x86.sse2.psubus.w";
+            } else if (util_get_cpu_caps()->has_altivec) {
+               if (type.width == 8)
+                  intrinsic = type.sign ? "llvm.ppc.altivec.vsubsbs" : "llvm.ppc.altivec.vsububs";
+               if (type.width == 16)
+                  intrinsic = type.sign ? "llvm.ppc.altivec.vsubshs" : "llvm.ppc.altivec.vsubuhs";
+            }
+         }
+         if (type.width * type.length == 256) {
+            if (util_get_cpu_caps()->has_avx2) {
+               if (type.width == 8)
+                  intrinsic = type.sign ? "llvm.x86.avx2.psubs.b" : "llvm.x86.avx2.psubus.b";
+               if (type.width == 16)
+                  intrinsic = type.sign ? "llvm.x86.avx2.psubs.w" : "llvm.x86.avx2.psubus.w";
+            }
+         }
+#endif
       }
 
       if (intrinsic)
@@ -1665,7 +1750,7 @@
 arch_rounding_available(const struct lp_type type)
 {
    if ((util_get_cpu_caps()->has_sse4_1 &&
-       (type.length == 1 || type.length == 2 ||
+       (type.length == 1 || (LLVM_VERSION_MAJOR >= 8 && type.length == 2) ||
         type.width * type.length == 128)) ||
        (util_get_cpu_caps()->has_avx && type.width * type.length == 256) ||
        (util_get_cpu_caps()->has_avx512f && type.width * type.length == 512))
diff --git src/gallium/auxiliary/gallivm/lp_bld_assert.c src/gallium/auxiliary/gallivm/lp_bld_assert.c
--- src/gallium/auxiliary/gallivm/lp_bld_assert.c
+++ src/gallium/auxiliary/gallivm/lp_bld_assert.c
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 #include "util/u_debug.h"
+#include "lp_bld.h"
 #include "lp_bld_assert.h"
 #include "lp_bld_init.h"
 #include "lp_bld_const.h"
diff --git src/gallium/auxiliary/gallivm/lp_bld_debug.cpp src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
--- src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+++ src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
@@ -292,31 +292,63 @@
 
    if (kind == LLVMHalfTypeKind)
       return LLVMDIBuilderCreateBasicType(
-         gallivm->di_builder, "float16_t", strlen("float16_t"), 16, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
+         gallivm->di_builder, "float16_t", strlen("float16_t"), 16, llvm::dwarf::DW_ATE_float
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
    if (kind == LLVMFloatTypeKind)
       return LLVMDIBuilderCreateBasicType(
-         gallivm->di_builder, "float", strlen("float"), 32, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
+         gallivm->di_builder, "float", strlen("float"), 32, llvm::dwarf::DW_ATE_float
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
    if (kind == LLVMDoubleTypeKind)
       return LLVMDIBuilderCreateBasicType(
-         gallivm->di_builder, "double", strlen("double"), 64, llvm::dwarf::DW_ATE_float, LLVMDIFlagZero);
+         gallivm->di_builder, "double", strlen("double"), 64, llvm::dwarf::DW_ATE_float
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
 
    if (kind == LLVMIntegerTypeKind) {
       uint32_t bit_size = LLVMGetIntTypeWidth(type);
       if (bit_size == 1)
          return LLVMDIBuilderCreateBasicType(
-            gallivm->di_builder, "bool", strlen("bool"), 1, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
+            gallivm->di_builder, "bool", strlen("bool"), 1, llvm::dwarf::DW_ATE_unsigned
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
       if (bit_size == 8)
          return LLVMDIBuilderCreateBasicType(
-            gallivm->di_builder, "int8_t", strlen("int8_t"), 8, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
+            gallivm->di_builder, "int8_t", strlen("int8_t"), 8, llvm::dwarf::DW_ATE_unsigned
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
       if (bit_size == 16)
          return LLVMDIBuilderCreateBasicType(
-            gallivm->di_builder, "int16_t", strlen("int16_t"), 16, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
+            gallivm->di_builder, "int16_t", strlen("int16_t"), 16, llvm::dwarf::DW_ATE_unsigned
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
       if (bit_size == 32)
          return LLVMDIBuilderCreateBasicType(
-            gallivm->di_builder, "int32_t", strlen("int32_t"), 32, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
+            gallivm->di_builder, "int32_t", strlen("int32_t"), 32, llvm::dwarf::DW_ATE_unsigned
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
       if (bit_size == 64)
          return LLVMDIBuilderCreateBasicType(
-            gallivm->di_builder, "int64_t", strlen("int64_t"), 64, llvm::dwarf::DW_ATE_unsigned, LLVMDIFlagZero);
+            gallivm->di_builder, "int64_t", strlen("int64_t"), 64, llvm::dwarf::DW_ATE_unsigned
+#if LLVM_VERSION_MAJOR >= 8
+            , LLVMDIFlagZero
+#endif
+            );
    }
 
    if (kind == LLVMFunctionTypeKind) {
@@ -385,7 +417,11 @@
 
       LLVMDIBuilderCreateCompileUnit(
          gallivm->di_builder, LLVMDWARFSourceLanguageC11, gallivm->file, gallivm->file_name, strlen(gallivm->file_name),
-         0, NULL, 0, 0, NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
+         0, NULL, 0, 0, NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0
+#if LLVM_VERSION_MAJOR >= 8
+            , "/", 1, "", 0
+#endif
+         );
    }
 
    LLVMMetadataRef di_function_type = lp_bld_debug_info_type(gallivm, func_type);
diff --git src/gallium/auxiliary/gallivm/lp_bld_misc.cpp src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
--- src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -547,6 +547,10 @@
       LLVMSetTarget(M, "arm64-apple-darwin");
 #   endif
 
+#  elif DETECT_ARCH_PPC_64
+    LLVMSetTarget(M, "powerpc64-apple-darwin");
+#  elif DETECT_ARCH_PPC
+    LLVMSetTarget(M, "powerpc-apple-darwin");
 #  else
 #    error Unsupported architecture for MCJIT on Apple.
 #  endif
diff --git src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
--- src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
+++ src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c
@@ -4393,11 +4393,13 @@
    case nir_atomic_op_umax: return LLVMAtomicRMWBinOpUMax;
    case nir_atomic_op_imin: return LLVMAtomicRMWBinOpMin;
    case nir_atomic_op_imax: return LLVMAtomicRMWBinOpMax;
+#if LLVM_VERSION_MAJOR >= 9
    case nir_atomic_op_fadd: return LLVMAtomicRMWBinOpFAdd;
 #if LLVM_VERSION_MAJOR >= 15
    case nir_atomic_op_fmin: return LLVMAtomicRMWBinOpFMin;
    case nir_atomic_op_fmax: return LLVMAtomicRMWBinOpFMax;
 #endif
+#endif
    default:          UNREACHABLE("Unexpected atomic");
    }
 }
@@ -5719,10 +5721,14 @@
       bld->instr = instr;
 
       if (gallivm->di_builder && gallivm->file_name && instr->has_debug_info) {
+#if LLVM_VERSION_MAJOR >= 9
          nir_instr_debug_info *debug_info = nir_instr_get_debug_info(instr);
          LLVMMetadataRef di_loc = LLVMDIBuilderCreateDebugLocation(
             gallivm->context, debug_info->nir_line, 1, gallivm->di_function, NULL);
          LLVMSetCurrentDebugLocation2(gallivm->builder, di_loc);
+#else
+         LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
 
          LLVMBuildStore(gallivm->builder, mask_vec(bld), bld->debug_exec_mask);
       }
diff --git src/gallium/auxiliary/gallivm/lp_bld_passmgr.c src/gallium/auxiliary/gallivm/lp_bld_passmgr.c
--- src/gallium/auxiliary/gallivm/lp_bld_passmgr.c
+++ src/gallium/auxiliary/gallivm/lp_bld_passmgr.c
@@ -31,23 +31,38 @@
 #include "lp_bld_debug.h"
 #include "lp_bld_passmgr.h"
 
-#define USE_NEW_PASS (LLVM_VERSION_MAJOR >= 15)
+#if LLVM_VERSION_MAJOR >= 15
+#define HAVE_CORO 0
+#define USE_NEW_PASS 1
+#elif LLVM_VERSION_MAJOR >= 8
+#define HAVE_CORO 1
+#define USE_NEW_PASS 0
+#else
+#define HAVE_CORO 0
+#define USE_NEW_PASS 0
+#endif
 
 #if USE_NEW_PASS == 1
 #include <llvm-c/Transforms/PassBuilder.h>
-#else
+#elif HAVE_CORO == 1
 #include <llvm-c/Transforms/Scalar.h>
 #include <llvm-c/Transforms/Utils.h>
 #if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
 #include <llvm-c/Transforms/IPO.h>
 #endif
 #include <llvm-c/Transforms/Coroutines.h>
+#else
+#include <llvm-c/Transforms/InstCombine.h>
+#include <llvm-c/Transforms/Scalar.h>
+#include <llvm-c/Transforms/Utils.h>
 #endif
 
 #if USE_NEW_PASS == 0
 struct lp_passmgr {
    LLVMPassManagerRef passmgr;
+#if HAVE_CORO == 1
    LLVMPassManagerRef cgpassmgr;
+#endif
 };
 #else
 struct lp_passmgr;
@@ -68,13 +83,16 @@
       return false;
    }
 
+#if HAVE_CORO == 1
    mgr->cgpassmgr = LLVMCreatePassManager();
+#endif
    /*
     * TODO: some per module pass manager with IPO passes might be helpful -
     * the generated texture functions may benefit from inlining if they are
     * simple, or constant propagation into them, etc.
     */
 
+#if HAVE_CORO == 1
 #if LLVM_VERSION_MAJOR <= 8 && (DETECT_ARCH_AARCH64 || DETECT_ARCH_ARM || DETECT_ARCH_S390 || DETECT_ARCH_MIPS64)
    LLVMAddArgumentPromotionPass(mgr->cgpassmgr);
    LLVMAddFunctionAttrsPass(mgr->cgpassmgr);
@@ -82,6 +100,7 @@
    LLVMAddCoroEarlyPass(mgr->cgpassmgr);
    LLVMAddCoroSplitPass(mgr->cgpassmgr);
    LLVMAddCoroElidePass(mgr->cgpassmgr);
+#endif
 
    if ((gallivm_perf & GALLIVM_PERF_NO_OPT) == 0) {
       /*
@@ -120,8 +139,10 @@
        */
       LLVMAddPromoteMemoryToRegisterPass(mgr->passmgr);
    }
+#if HAVE_CORO == 1
    LLVMAddCoroCleanupPass(mgr->passmgr);
 #endif
+#endif
    *mgr_p = mgr;
    return true;
 }
@@ -162,7 +183,9 @@
    LLVMRunPasses(module, passes, tm, opts);
    LLVMDisposePassBuilderOptions(opts);
 #else
+#if HAVE_CORO == 1
    LLVMRunPassManager(mgr->cgpassmgr, module);
+#endif
    /* Run optimization passes */
    LLVMInitializeFunctionPassManager(mgr->passmgr);
    LLVMValueRef func;
@@ -203,10 +226,12 @@
       mgr->passmgr = NULL;
    }
 
+#if HAVE_CORO == 1
    if (mgr->cgpassmgr) {
       LLVMDisposePassManager(mgr->cgpassmgr);
       mgr->cgpassmgr = NULL;
    }
+#endif
    FREE(mgr);
 #endif
 }
diff --git src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
--- src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -4666,12 +4666,14 @@
       case LLVMAtomicRMWBinOpUMin:
          valid &= integer;
          break;
+#if LLVM_VERSION_MAJOR >= 9
       case LLVMAtomicRMWBinOpFAdd:
       case LLVMAtomicRMWBinOpFSub:
 #if LLVM_VERSION_MAJOR >= 15
          case LLVMAtomicRMWBinOpFMax:
          case LLVMAtomicRMWBinOpFMin:
 #endif
+#endif
          valid &= !integer;
          break;
       default:
diff --git src/gallium/auxiliary/gallivm/lp_bld_struct.c src/gallium/auxiliary/gallivm/lp_bld_struct.c
--- src/gallium/auxiliary/gallivm/lp_bld_struct.c
+++ src/gallium/auxiliary/gallivm/lp_bld_struct.c
@@ -34,6 +34,7 @@
  */
 
 
+#include "lp_bld.h"
 #include "lp_bld_const.h"
 #include "lp_bld_debug.h"
 #include "lp_bld_struct.h"
diff --git src/gallium/auxiliary/gallivm/lp_bld_type.h src/gallium/auxiliary/gallivm/lp_bld_type.h
--- src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -39,7 +39,7 @@
 
 #include "util/format/u_format.h"
 
-#include <llvm-c/Core.h>
+#include "gallivm/lp_bld.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git src/gallium/drivers/llvmpipe/lp_screen.c src/gallium/drivers/llvmpipe/lp_screen.c
--- src/gallium/drivers/llvmpipe/lp_screen.c
+++ src/gallium/drivers/llvmpipe/lp_screen.c
@@ -137,6 +137,10 @@
          break;
       case MESA_SHADER_TESS_CTRL:
       case MESA_SHADER_TESS_EVAL:
+         /* Tessellation shader needs llvm coroutines support */
+         if (!GALLIVM_COROUTINES)
+            continue;
+         FALLTHROUGH;
       case MESA_SHADER_VERTEX:
       case MESA_SHADER_GEOMETRY:
          draw_init_shader_caps(caps);
@@ -272,7 +276,8 @@
    caps->vertex_color_clamped = true;
    caps->glsl_feature_level_compatibility =
    caps->glsl_feature_level = 460;
-   caps->compute = true;
+   /* Compute (and mesh/task) shader dispatch needs llvm coroutines support */
+   caps->compute = GALLIVM_COROUTINES;
    caps->user_vertex_buffers = true;
    caps->tgsi_texcoord = true;
    caps->draw_indirect = true;
@@ -395,7 +400,7 @@
    /* We just pretend that every size is accelerated */
    caps->hw_clear_buffer_sizes = ~0;
 
-   caps->mesh_shader = true;
+   caps->mesh_shader = GALLIVM_COROUTINES;
 
    caps->mesh.max_task_work_group_total_count = 4194304;
    caps->mesh.max_mesh_work_group_total_count = 4194304;
diff --git src/gallium/drivers/llvmpipe/lp_state_cs.c src/gallium/drivers/llvmpipe/lp_state_cs.c
--- src/gallium/drivers/llvmpipe/lp_state_cs.c
+++ src/gallium/drivers/llvmpipe/lp_state_cs.c
@@ -592,8 +592,12 @@
       LLVMPositionBuilderAtEnd(builder, block);
 
       if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
          LLVMSetCurrentDebugLocation2(
            gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+         LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
       }
 
       if (is_mesh) {
@@ -729,8 +733,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    struct lp_build_loop_state loop_state;
diff --git src/gallium/drivers/llvmpipe/lp_state_fs.c src/gallium/drivers/llvmpipe/lp_state_fs.c
--- src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -3344,8 +3344,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    /* code generated texture sampling */
diff --git src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c
--- src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c
+++ src/gallium/drivers/llvmpipe/lp_state_fs_linear_llvm.c
@@ -330,8 +330,12 @@
    LLVMPositionBuilderAtEnd(builder, block);
 
    if (gallivm->di_function) {
+#if LLVM_VERSION_MAJOR >= 9
       LLVMSetCurrentDebugLocation2(
          gallivm->builder, LLVMDIBuilderCreateDebugLocation(gallivm->context, 0, 0, gallivm->di_function, NULL));
+#else
+      LLVMSetCurrentDebugLocation(gallivm->builder, NULL);
+#endif
    }
 
    struct lp_build_context bld;
diff --git src/gallium/drivers/llvmpipe/lp_test_arit.c src/gallium/drivers/llvmpipe/lp_test_arit.c
--- src/gallium/drivers/llvmpipe/lp_test_arit.c
+++ src/gallium/drivers/llvmpipe/lp_test_arit.c
@@ -489,7 +489,7 @@
              !util_get_cpu_caps()->has_altivec &&
              !util_get_cpu_caps()->has_neon &&
              DETECT_ARCH_S390 == false &&
-             !util_get_cpu_caps()->has_sse4_1 &&
+             !(util_get_cpu_caps()->has_sse4_1 && LLVM_VERSION_MAJOR >= 8) &&
              ref != roundf(testval)) {
             /* FIXME: The generic (non SSE) path in lp_build_iround, which is
              * always taken for length==2 regardless of native round support,
diff --git src/glx/glxext.c src/glx/glxext.c
--- src/glx/glxext.c
+++ src/glx/glxext.c
@@ -47,6 +47,21 @@
 #include <dlfcn.h>
 #endif
 
+/*
+ * __builtin_available() is a clang builtin; it is unavailable in GCC.  The
+ * macOS 26.0-26.5 AppleGL breakage it is used to work around below cannot
+ * apply to a deployment target that predates those releases, so fall back to
+ * "available" and keep the pre-existing behaviour of electing AppleGL.
+ */
+#if defined(__has_builtin)
+#  if __has_builtin(__builtin_available)
+#    define GLX_BUILTIN_AVAILABLE(...) __builtin_available(__VA_ARGS__)
+#  endif
+#endif
+#ifndef GLX_BUILTIN_AVAILABLE
+#  define GLX_BUILTIN_AVAILABLE(...) 1
+#endif
+
 #define __GLX_MIN_CONFIG_PROPS	18
 #define __GLX_EXT_CONFIG_PROPS	32
 
@@ -1053,10 +1068,10 @@
       if (env) {
          if (!strcmp(env, "applegl"))
             glx_driver |= GLX_DRIVER_APPLEGL;
-      } else if (__builtin_available(macOS 26.6, *)) {
+      } else if (GLX_BUILTIN_AVAILABLE(macOS 26.6, *)) {
          /* macOS 26.6 fixed the breakage described below, so elect AppleGL as usual. */
          glx_driver |= GLX_DRIVER_APPLEGL;
-      } else if (__builtin_available(macOS 26.0, *)) {
+      } else if (GLX_BUILTIN_AVAILABLE(macOS 26.0, *)) {
          /* AppleGL is not working on macOS 26.0 through 26.5
           * (https://github.com/XQuartz/XQuartz/issues/446); skip its election and let the
           * screen-creation walk fall through to drisw / zink.
