[Build] Fix GCC build (#24756)

Building IREE with gcc intermittently runs out of memory and fails. 

 - Limit the number of cores used for building to prevent this.
 - Disable erroneous warning (on GCC) "array subscript is partly outside
array bounds".

---------

Signed-off-by: Jelle Schühmacher <schuehmacher@roofline.ai>
Signed-off-by: Artem Gindinson <gindinson@roofline.ai>
Signed-off-by: Jelle Schuhmacher <schuehmacher@roofline.ai>
Co-authored-by: Artem Gindinson <gindinson@roofline.ai>
diff --git a/.github/workflows/ci_linux_x64_gcc.yml b/.github/workflows/ci_linux_x64_gcc.yml
index a8750b5..868617e 100644
--- a/.github/workflows/ci_linux_x64_gcc.yml
+++ b/.github/workflows/ci_linux_x64_gcc.yml
@@ -37,6 +37,8 @@
           CMAKE_BUILD_TYPE: Release
           IREE_TARGET_BACKEND_WEBGPU_SPIRV: OFF
           IREE_BUILD_SETUP_PYTHON_VENV: ${{ env.BUILD_DIR }}/.venv
+          # Prevent OOM, cap build parallelism to fit the standard 4-vCPU/16-GB hosted runner.
+          CMAKE_BUILD_PARALLEL_LEVEL: 4
         run: ./build_tools/cmake/build_all.sh "${BUILD_DIR}"
 
       - name: Post to Discord on Failure
diff --git a/build_tools/cmake/iree_copts.cmake b/build_tools/cmake/iree_copts.cmake
index 505d242..b9de289 100644
--- a/build_tools/cmake/iree_copts.cmake
+++ b/build_tools/cmake/iree_copts.cmake
@@ -232,6 +232,10 @@
     "-Wno-unused-but-set-variable"
     "-Wno-misleading-indentation"
 
+  GCC_LT_12
+    # False positives GCC 11 on SmallDenseMap instantiations. Fixed in GCC 12
+    $<$<COMPILE_LANGUAGE:CXX>:-Wno-error=array-bounds>
+
   GCC_GTE_13
     # False positives? Not useful? https://stackoverflow.com/a/78760067
     $<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>
diff --git a/build_tools/cmake/iree_macros.cmake b/build_tools/cmake/iree_macros.cmake
index 8a6dddd..62226aa 100644
--- a/build_tools/cmake/iree_macros.cmake
+++ b/build_tools/cmake/iree_macros.cmake
@@ -391,7 +391,7 @@
     _IREE_SELECTS
     ""
     ""
-    "ALL;CLANG;CLANG_GTE_10;CLANG_GTE_12;CLANG_CL;MSVC;GCC;GCC_GTE_13;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
+    "ALL;CLANG;CLANG_GTE_10;CLANG_GTE_12;CLANG_CL;MSVC;GCC;GCC_LT_12;GCC_GTE_13;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
   )
   # OPTS is a variable containing the *name* of the variable being populated, so
   # we need to dereference it twice.
@@ -400,6 +400,9 @@
   if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
     list(APPEND _OPTS "${_IREE_SELECTS_GCC}")
     list(APPEND _OPTS "${_IREE_SELECTS_CLANG_OR_GCC}")
+    if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12)
+      list(APPEND _OPTS ${_IREE_SELECTS_GCC_LT_12})
+    endif()
     if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13)
       list(APPEND _OPTS ${_IREE_SELECTS_GCC_GTE_13})
     endif()
diff --git a/compiler/src/iree/compiler/Codegen/Utils/SliceUtils.cpp b/compiler/src/iree/compiler/Codegen/Utils/SliceUtils.cpp
index ac808c1..4f8c587 100644
--- a/compiler/src/iree/compiler/Codegen/Utils/SliceUtils.cpp
+++ b/compiler/src/iree/compiler/Codegen/Utils/SliceUtils.cpp
@@ -119,6 +119,9 @@
     }
     int64_t rank = cast<ShapedType>(value.getType()).getRank();
     int64_t outDimSize = std::min(rank, numLoops);
+    if (valueToGlobalDimMaps[value].size() < outDimSize) {
+      continue;
+    }
     for (int64_t i = 0; i < outDimSize; ++i) {
       indicesEquivalence.unionSets(valueToGlobalDimMaps[value][i],
                                    operationToGlobalDimMaps[op][i]);
@@ -139,7 +142,8 @@
   for (OpOperand &operand : op->getOpOperands()) {
     Value value = operand.get();
     if (!valueToGlobalDimMaps.contains(value) ||
-        numLoops != cast<ShapedType>(value.getType()).getRank()) {
+        numLoops != cast<ShapedType>(value.getType()).getRank() ||
+        valueToGlobalDimMaps[value].size() < numLoops) {
       continue;
     }
     for (int64_t i = 0; i < numLoops; ++i) {