Skip to content

[GlobalISel] use constexpr LLT types when creating ISel data#191574

Merged
michalpaszkowski merged 1 commit into
llvm:mainfrom
stanleygambarin:extended_llt_fix
Apr 14, 2026
Merged

[GlobalISel] use constexpr LLT types when creating ISel data#191574
michalpaszkowski merged 1 commit into
llvm:mainfrom
stanleygambarin:extended_llt_fix

Conversation

@stanleygambarin

Copy link
Copy Markdown
Contributor

The GlobalISel uses a lookup table to map LLTs which is constructed
prior to initialization of extended LLT functionality, resulting in
ANY_SCALAR entries. During instruction selection, a hash-based
lookup is done on actual INTEGER/FLOAT LLTs. But hash values of
ANY_SCALAR do not match those of INTEGER/FLOAT, causing a failure.

Workaround is the use constexpr LLT, which encodes INTEGER/FLOAT LLT.

Assisted-by: Claude Opus 4.6

@llvmbot

llvmbot commented Apr 10, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-llvm-globalisel

Author: Stanley Gambarin (stanleygambarin)

Changes

The GlobalISel uses a lookup table to map LLTs which is constructed
prior to initialization of extended LLT functionality, resulting in
ANY_SCALAR entries. During instruction selection, a hash-based
lookup is done on actual INTEGER/FLOAT LLTs. But hash values of
ANY_SCALAR do not match those of INTEGER/FLOAT, causing a failure.

Workaround is the use constexpr LLT, which encodes INTEGER/FLOAT LLT.

Assisted-by: Claude Opus 4.6


Full diff: https://github.com/llvm/llvm-project/pull/191574.diff

3 Files Affected:

  • (modified) llvm/include/llvm/CodeGenTypes/LowLevelType.h (+8)
  • (modified) llvm/unittests/CodeGen/LowLevelTypeTest.cpp (+110)
  • (modified) llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp (+30-4)
diff --git a/llvm/include/llvm/CodeGenTypes/LowLevelType.h b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
index 920bd9ad9bf51..884249ae99bcd 100644
--- a/llvm/include/llvm/CodeGenTypes/LowLevelType.h
+++ b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
@@ -96,6 +96,14 @@ class LLT {
     return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
   }
 
+  /// Constexpr integer type constructor that always produces the INTEGER kind,
+  /// regardless of the ExtendedLLT flag. Used by generated code (e.g.
+  /// TypeObjects arrays in GlobalISel) that must have stable types at static
+  /// initialization time.
+  static constexpr LLT integerExact(unsigned SizeInBits) {
+    return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
+  }
+
   static LLT floatingPoint(const FpSemantics &Sem) {
     if (!getUseExtended())
       return LLT::scalar(
diff --git a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
index 411d834647d70..d8a170c58cdca 100644
--- a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
+++ b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/LowLevelTypeUtils.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
@@ -449,4 +450,113 @@ TEST(LowLevelTypeTest, IsScalableVector) {
   EXPECT_TRUE(LLT::scalable_vector(2, 32).isScalableVector());
   EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector());
 }
+
+// Demonstrate that LLT::integer() and LLT::floatIEEE() produce different types
+// depending on the ExtendedLLT flag, which causes DenseMap lookup failures when
+// a TypeObjects array is statically initialized before setUseExtended(true).
+// This is the bug fixed by integerExact() and the float-specific constructors
+// in the GlobalISel TableGen emitter.
+TEST(LowLevelTypeTest, ExtendedLLTDenseMapConsistency) {
+  // Save and restore the ExtendedLLT state.
+  bool OldExtended = LLT::getUseExtended();
+
+  // --- Phase 1: simulate static initialization (ExtendedLLT = false) ---
+  LLT::setUseExtended(false);
+
+  // These mimic what the *old* generated TypeObjects array contained:
+  // LLT::integer(N) falls back to LLT::scalar(N) when extended is off.
+  LLT OldI16 = LLT::integer(16);
+  LLT OldI32 = LLT::integer(32);
+  LLT OldF32 = LLT::floatIEEE(32);
+  LLT OldF64 = LLT::floatIEEE(64);
+
+  // All of these are just LLT::scalar(N) — no integer/float distinction.
+  EXPECT_TRUE(OldI16.isAnyScalar());
+  EXPECT_FALSE(OldI16.isInteger());
+  EXPECT_TRUE(OldI32.isAnyScalar());
+  EXPECT_FALSE(OldF32.isFloat());
+
+  // Build a DenseMap as ExecInfoTy does: TypeObjects[i] -> i
+  SmallDenseMap<LLT, unsigned, 64> TypeIDMap;
+  TypeIDMap[OldI16] = 2;   // GILLT_i16
+  TypeIDMap[OldI32] = 3;   // GILLT_i32
+  TypeIDMap[OldF32] = 8;   // GILLT_f32
+  TypeIDMap[OldF64] = 9;   // GILLT_f64
+
+  // --- Phase 2: simulate runtime (ExtendedLLT = true) ---
+  LLT::setUseExtended(true);
+
+  // At runtime, getLLTForType / MRI.getType() produces extended types.
+  LLT RuntimeI32 = LLT::integer(32);
+  LLT RuntimeF32 = LLT::floatIEEE(32);
+
+  // These are properly typed now.
+  EXPECT_TRUE(RuntimeI32.isInteger());
+  EXPECT_TRUE(RuntimeF32.isFloat());
+
+  // operator== considers scalar(32) and integer(32) equal (via the
+  // isAnyScalar() wildcard path), but their raw data differs:
+  EXPECT_EQ(OldI32, RuntimeI32);
+  EXPECT_NE(OldI32.getUniqueRAWLLTData(), RuntimeI32.getUniqueRAWLLTData());
+
+  // Similarly for float types:
+  EXPECT_EQ(OldF32, RuntimeF32);
+  EXPECT_NE(OldF32.getUniqueRAWLLTData(), RuntimeF32.getUniqueRAWLLTData());
+
+  // BUG: DenseMap hashes are based on getUniqueRAWLLTData(), so
+  // hash(scalar(32)) != hash(integer(32)) even though they're operator==.
+  // This violates the DenseMap contract and causes unreliable lookups.
+  EXPECT_NE(DenseMapInfo<LLT>::getHashValue(OldI32),
+            DenseMapInfo<LLT>::getHashValue(RuntimeI32));
+  EXPECT_NE(DenseMapInfo<LLT>::getHashValue(OldF32),
+            DenseMapInfo<LLT>::getHashValue(RuntimeF32));
+
+  // --- Phase 3: show that integerExact / float32 fix the problem ---
+  SmallDenseMap<LLT, unsigned, 64> FixedTypeIDMap;
+
+  // New generated code uses integerExact() and float32() etc., which are
+  // constexpr and always produce the correct Kind regardless of ExtendedLLT.
+  FixedTypeIDMap[LLT::integerExact(16)] = 2;
+  FixedTypeIDMap[LLT::integerExact(32)] = 3;
+  FixedTypeIDMap[LLT::float32()] = 8;
+  FixedTypeIDMap[LLT::float64()] = 9;
+  FixedTypeIDMap[LLT::fixed_vector(4, LLT::integerExact(16))] = 18;
+
+  LLT RuntimeI16 = LLT::integer(16);
+  LLT RuntimeV4I16 = LLT::fixed_vector(4, RuntimeI16);
+  LLT RuntimeF64 = LLT::floatIEEE(64);
+
+  // The raw data of integerExact(N) matches integer(N) when extended is on:
+  EXPECT_EQ(LLT::integerExact(32).getUniqueRAWLLTData(),
+            RuntimeI32.getUniqueRAWLLTData());
+  EXPECT_EQ(LLT::float32().getUniqueRAWLLTData(),
+            RuntimeF32.getUniqueRAWLLTData());
+
+  // So DenseMap hashes also match:
+  EXPECT_EQ(DenseMapInfo<LLT>::getHashValue(LLT::integerExact(32)),
+            DenseMapInfo<LLT>::getHashValue(RuntimeI32));
+  EXPECT_EQ(DenseMapInfo<LLT>::getHashValue(LLT::float32()),
+            DenseMapInfo<LLT>::getHashValue(RuntimeF32));
+
+  // Runtime lookups now SUCCEED:
+  auto Fix_I32 = FixedTypeIDMap.find(RuntimeI32);
+  auto Fix_F32 = FixedTypeIDMap.find(RuntimeF32);
+  auto Fix_F64 = FixedTypeIDMap.find(RuntimeF64);
+  auto Fix_V4I16 = FixedTypeIDMap.find(RuntimeV4I16);
+
+  ASSERT_NE(Fix_I32, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_I32->second, 3u);
+
+  ASSERT_NE(Fix_F32, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_F32->second, 8u);
+
+  ASSERT_NE(Fix_F64, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_F64->second, 9u);
+
+  ASSERT_NE(Fix_V4I16, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_V4I16->second, 18u);
+
+  LLT::setUseExtended(OldExtended);
+}
+
 }
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index 1968097f91983..48e1db1077c28 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -408,10 +408,36 @@ void LLTCodeGen::emitCxxEnumValue(raw_ostream &OS) const {
   llvm_unreachable("Unhandled LLT");
 }
 
+/// Emit a constexpr LLT constructor call for an IEEE floating-point type.
+/// Using specific constructors (float16, float32, etc.) instead of the generic
+/// floatIEEE() avoids static initialization order issues: floatIEEE() calls
+/// getUseExtended() which may return false during static init, producing
+/// LLT::scalar() instead of the intended float type.
+static void emitFloatIEEECxxConstructorCall(raw_ostream &OS,
+                                            unsigned SizeInBits) {
+  switch (SizeInBits) {
+  case 16:
+    OS << "LLT::float16()";
+    break;
+  case 32:
+    OS << "LLT::float32()";
+    break;
+  case 64:
+    OS << "LLT::float64()";
+    break;
+  case 128:
+    OS << "LLT::float128()";
+    break;
+  default:
+    OS << "LLT::floatIEEE(" << SizeInBits << ")";
+    break;
+  }
+}
+
 void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
   if (Ty.isScalar()) {
     if (Ty.isInteger())
-      OS << "LLT::integer(" << Ty.getScalarSizeInBits() << ")";
+      OS << "LLT::integerExact(" << Ty.getScalarSizeInBits() << ")";
     else if (Ty.isBFloat16())
       OS << "LLT::bfloat16()";
     else if (Ty.isPPCF128())
@@ -419,7 +445,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
     else if (Ty.isX86FP80())
       OS << "LLT::x86fp80()";
     else if (Ty.isFloat())
-      OS << "LLT::floatIEEE(" << Ty.getScalarSizeInBits() << ")";
+      emitFloatIEEECxxConstructorCall(OS, Ty.getScalarSizeInBits());
     else
       OS << "LLT::scalar(" << Ty.getScalarSizeInBits() << ")";
     return;
@@ -433,7 +459,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
 
     LLT ElemTy = Ty.getElementType();
     if (ElemTy.isInteger())
-      OS << "LLT::integer(" << ElemTy.getScalarSizeInBits() << ")";
+      OS << "LLT::integerExact(" << ElemTy.getScalarSizeInBits() << ")";
     else if (ElemTy.isBFloat16())
       OS << "LLT::bfloat16()";
     else if (ElemTy.isPPCF128())
@@ -441,7 +467,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
     else if (ElemTy.isX86FP80())
       OS << "LLT::x86fp80()";
     else if (ElemTy.isFloat())
-      OS << "LLT::floatIEEE(" << ElemTy.getScalarSizeInBits() << ")";
+      emitFloatIEEECxxConstructorCall(OS, ElemTy.getScalarSizeInBits());
     else
       OS << "LLT::scalar(" << Ty.getScalarSizeInBits() << ")";
     OS << ")";

@llvmbot

llvmbot commented Apr 10, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-tablegen

Author: Stanley Gambarin (stanleygambarin)

Changes

The GlobalISel uses a lookup table to map LLTs which is constructed
prior to initialization of extended LLT functionality, resulting in
ANY_SCALAR entries. During instruction selection, a hash-based
lookup is done on actual INTEGER/FLOAT LLTs. But hash values of
ANY_SCALAR do not match those of INTEGER/FLOAT, causing a failure.

Workaround is the use constexpr LLT, which encodes INTEGER/FLOAT LLT.

Assisted-by: Claude Opus 4.6


Full diff: https://github.com/llvm/llvm-project/pull/191574.diff

3 Files Affected:

  • (modified) llvm/include/llvm/CodeGenTypes/LowLevelType.h (+8)
  • (modified) llvm/unittests/CodeGen/LowLevelTypeTest.cpp (+110)
  • (modified) llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp (+30-4)
diff --git a/llvm/include/llvm/CodeGenTypes/LowLevelType.h b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
index 920bd9ad9bf51..884249ae99bcd 100644
--- a/llvm/include/llvm/CodeGenTypes/LowLevelType.h
+++ b/llvm/include/llvm/CodeGenTypes/LowLevelType.h
@@ -96,6 +96,14 @@ class LLT {
     return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
   }
 
+  /// Constexpr integer type constructor that always produces the INTEGER kind,
+  /// regardless of the ExtendedLLT flag. Used by generated code (e.g.
+  /// TypeObjects arrays in GlobalISel) that must have stable types at static
+  /// initialization time.
+  static constexpr LLT integerExact(unsigned SizeInBits) {
+    return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
+  }
+
   static LLT floatingPoint(const FpSemantics &Sem) {
     if (!getUseExtended())
       return LLT::scalar(
diff --git a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
index 411d834647d70..d8a170c58cdca 100644
--- a/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
+++ b/llvm/unittests/CodeGen/LowLevelTypeTest.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/LowLevelTypeUtils.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/LLVMContext.h"
@@ -449,4 +450,113 @@ TEST(LowLevelTypeTest, IsScalableVector) {
   EXPECT_TRUE(LLT::scalable_vector(2, 32).isScalableVector());
   EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector());
 }
+
+// Demonstrate that LLT::integer() and LLT::floatIEEE() produce different types
+// depending on the ExtendedLLT flag, which causes DenseMap lookup failures when
+// a TypeObjects array is statically initialized before setUseExtended(true).
+// This is the bug fixed by integerExact() and the float-specific constructors
+// in the GlobalISel TableGen emitter.
+TEST(LowLevelTypeTest, ExtendedLLTDenseMapConsistency) {
+  // Save and restore the ExtendedLLT state.
+  bool OldExtended = LLT::getUseExtended();
+
+  // --- Phase 1: simulate static initialization (ExtendedLLT = false) ---
+  LLT::setUseExtended(false);
+
+  // These mimic what the *old* generated TypeObjects array contained:
+  // LLT::integer(N) falls back to LLT::scalar(N) when extended is off.
+  LLT OldI16 = LLT::integer(16);
+  LLT OldI32 = LLT::integer(32);
+  LLT OldF32 = LLT::floatIEEE(32);
+  LLT OldF64 = LLT::floatIEEE(64);
+
+  // All of these are just LLT::scalar(N) — no integer/float distinction.
+  EXPECT_TRUE(OldI16.isAnyScalar());
+  EXPECT_FALSE(OldI16.isInteger());
+  EXPECT_TRUE(OldI32.isAnyScalar());
+  EXPECT_FALSE(OldF32.isFloat());
+
+  // Build a DenseMap as ExecInfoTy does: TypeObjects[i] -> i
+  SmallDenseMap<LLT, unsigned, 64> TypeIDMap;
+  TypeIDMap[OldI16] = 2;   // GILLT_i16
+  TypeIDMap[OldI32] = 3;   // GILLT_i32
+  TypeIDMap[OldF32] = 8;   // GILLT_f32
+  TypeIDMap[OldF64] = 9;   // GILLT_f64
+
+  // --- Phase 2: simulate runtime (ExtendedLLT = true) ---
+  LLT::setUseExtended(true);
+
+  // At runtime, getLLTForType / MRI.getType() produces extended types.
+  LLT RuntimeI32 = LLT::integer(32);
+  LLT RuntimeF32 = LLT::floatIEEE(32);
+
+  // These are properly typed now.
+  EXPECT_TRUE(RuntimeI32.isInteger());
+  EXPECT_TRUE(RuntimeF32.isFloat());
+
+  // operator== considers scalar(32) and integer(32) equal (via the
+  // isAnyScalar() wildcard path), but their raw data differs:
+  EXPECT_EQ(OldI32, RuntimeI32);
+  EXPECT_NE(OldI32.getUniqueRAWLLTData(), RuntimeI32.getUniqueRAWLLTData());
+
+  // Similarly for float types:
+  EXPECT_EQ(OldF32, RuntimeF32);
+  EXPECT_NE(OldF32.getUniqueRAWLLTData(), RuntimeF32.getUniqueRAWLLTData());
+
+  // BUG: DenseMap hashes are based on getUniqueRAWLLTData(), so
+  // hash(scalar(32)) != hash(integer(32)) even though they're operator==.
+  // This violates the DenseMap contract and causes unreliable lookups.
+  EXPECT_NE(DenseMapInfo<LLT>::getHashValue(OldI32),
+            DenseMapInfo<LLT>::getHashValue(RuntimeI32));
+  EXPECT_NE(DenseMapInfo<LLT>::getHashValue(OldF32),
+            DenseMapInfo<LLT>::getHashValue(RuntimeF32));
+
+  // --- Phase 3: show that integerExact / float32 fix the problem ---
+  SmallDenseMap<LLT, unsigned, 64> FixedTypeIDMap;
+
+  // New generated code uses integerExact() and float32() etc., which are
+  // constexpr and always produce the correct Kind regardless of ExtendedLLT.
+  FixedTypeIDMap[LLT::integerExact(16)] = 2;
+  FixedTypeIDMap[LLT::integerExact(32)] = 3;
+  FixedTypeIDMap[LLT::float32()] = 8;
+  FixedTypeIDMap[LLT::float64()] = 9;
+  FixedTypeIDMap[LLT::fixed_vector(4, LLT::integerExact(16))] = 18;
+
+  LLT RuntimeI16 = LLT::integer(16);
+  LLT RuntimeV4I16 = LLT::fixed_vector(4, RuntimeI16);
+  LLT RuntimeF64 = LLT::floatIEEE(64);
+
+  // The raw data of integerExact(N) matches integer(N) when extended is on:
+  EXPECT_EQ(LLT::integerExact(32).getUniqueRAWLLTData(),
+            RuntimeI32.getUniqueRAWLLTData());
+  EXPECT_EQ(LLT::float32().getUniqueRAWLLTData(),
+            RuntimeF32.getUniqueRAWLLTData());
+
+  // So DenseMap hashes also match:
+  EXPECT_EQ(DenseMapInfo<LLT>::getHashValue(LLT::integerExact(32)),
+            DenseMapInfo<LLT>::getHashValue(RuntimeI32));
+  EXPECT_EQ(DenseMapInfo<LLT>::getHashValue(LLT::float32()),
+            DenseMapInfo<LLT>::getHashValue(RuntimeF32));
+
+  // Runtime lookups now SUCCEED:
+  auto Fix_I32 = FixedTypeIDMap.find(RuntimeI32);
+  auto Fix_F32 = FixedTypeIDMap.find(RuntimeF32);
+  auto Fix_F64 = FixedTypeIDMap.find(RuntimeF64);
+  auto Fix_V4I16 = FixedTypeIDMap.find(RuntimeV4I16);
+
+  ASSERT_NE(Fix_I32, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_I32->second, 3u);
+
+  ASSERT_NE(Fix_F32, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_F32->second, 8u);
+
+  ASSERT_NE(Fix_F64, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_F64->second, 9u);
+
+  ASSERT_NE(Fix_V4I16, FixedTypeIDMap.end());
+  EXPECT_EQ(Fix_V4I16->second, 18u);
+
+  LLT::setUseExtended(OldExtended);
+}
+
 }
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index 1968097f91983..48e1db1077c28 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -408,10 +408,36 @@ void LLTCodeGen::emitCxxEnumValue(raw_ostream &OS) const {
   llvm_unreachable("Unhandled LLT");
 }
 
+/// Emit a constexpr LLT constructor call for an IEEE floating-point type.
+/// Using specific constructors (float16, float32, etc.) instead of the generic
+/// floatIEEE() avoids static initialization order issues: floatIEEE() calls
+/// getUseExtended() which may return false during static init, producing
+/// LLT::scalar() instead of the intended float type.
+static void emitFloatIEEECxxConstructorCall(raw_ostream &OS,
+                                            unsigned SizeInBits) {
+  switch (SizeInBits) {
+  case 16:
+    OS << "LLT::float16()";
+    break;
+  case 32:
+    OS << "LLT::float32()";
+    break;
+  case 64:
+    OS << "LLT::float64()";
+    break;
+  case 128:
+    OS << "LLT::float128()";
+    break;
+  default:
+    OS << "LLT::floatIEEE(" << SizeInBits << ")";
+    break;
+  }
+}
+
 void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
   if (Ty.isScalar()) {
     if (Ty.isInteger())
-      OS << "LLT::integer(" << Ty.getScalarSizeInBits() << ")";
+      OS << "LLT::integerExact(" << Ty.getScalarSizeInBits() << ")";
     else if (Ty.isBFloat16())
       OS << "LLT::bfloat16()";
     else if (Ty.isPPCF128())
@@ -419,7 +445,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
     else if (Ty.isX86FP80())
       OS << "LLT::x86fp80()";
     else if (Ty.isFloat())
-      OS << "LLT::floatIEEE(" << Ty.getScalarSizeInBits() << ")";
+      emitFloatIEEECxxConstructorCall(OS, Ty.getScalarSizeInBits());
     else
       OS << "LLT::scalar(" << Ty.getScalarSizeInBits() << ")";
     return;
@@ -433,7 +459,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
 
     LLT ElemTy = Ty.getElementType();
     if (ElemTy.isInteger())
-      OS << "LLT::integer(" << ElemTy.getScalarSizeInBits() << ")";
+      OS << "LLT::integerExact(" << ElemTy.getScalarSizeInBits() << ")";
     else if (ElemTy.isBFloat16())
       OS << "LLT::bfloat16()";
     else if (ElemTy.isPPCF128())
@@ -441,7 +467,7 @@ void LLTCodeGen::emitCxxConstructorCall(raw_ostream &OS) const {
     else if (ElemTy.isX86FP80())
       OS << "LLT::x86fp80()";
     else if (ElemTy.isFloat())
-      OS << "LLT::floatIEEE(" << ElemTy.getScalarSizeInBits() << ")";
+      emitFloatIEEECxxConstructorCall(OS, ElemTy.getScalarSizeInBits());
     else
       OS << "LLT::scalar(" << Ty.getScalarSizeInBits() << ")";
     OS << ")";

@github-actions

github-actions Bot commented Apr 10, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

@stanleygambarin

Copy link
Copy Markdown
Contributor Author

alternative solution would be to modify LLT::operator==

bool operator==(const LLT &RHS) const {
// When extended types are in use, require exact kind matching
// for scalar types — no ANY_SCALAR wildcard.
if (getUseExtended())
return Info == RHS.Info && RawData == RHS.RawData;

// Legacy behavior for non-extended mode.
if (isAnyScalar() || RHS.isAnyScalar())
return isScalar() == RHS.isScalar() &&
getScalarSizeInBits() == RHS.getScalarSizeInBits();
...
}

however, that would break every comparison between integer(N) and scalar(N) when extended LLT is enabled, requiring complete switch to extended LLT for the whole backend.

@michalpaszkowski

michalpaszkowski commented Apr 11, 2026

Copy link
Copy Markdown
Member

@stanleygambarin Thanks for the patch! I am fine with either solution. I don't see any downsides to the workaround apart from the fact that it is a workaround and the original problem is still present. The workaround is somewhat self-contained and we could always go with the alternative later.

Also GlobalISelEmitter/GlobalISelEmitter.td would need to be updated to use LLT::integerExact(32) instead of LLT::integer(32).

Going with the alternative would solve the actual problem, but will force each backend with ExtendedLLT=true to make changes and use the types explicitly. This is not a problem now in the upstream, but might potentially be for some backends in the downstream that rely on PR #155107.

CC @DenisGZM @tgymnich I am also adding reviewers from the #155107 Please take a look at the unit test and let us know your thoughts/preferences.

@michalpaszkowski
michalpaszkowski self-requested a review April 11, 2026 00:12
@github-actions

github-actions Bot commented Apr 11, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 193592 tests passed
  • 5044 tests skipped

✅ The build succeeded and all tests passed.

@github-actions

github-actions Bot commented Apr 11, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 133510 tests passed
  • 3096 tests skipped

✅ The build succeeded and all tests passed.

@QuantumSegfault

Copy link
Copy Markdown
Contributor

Thank you! I believe this solves #190873 that I was running into.

In regards to preference, I don't really have one. I just want it to work. I'm building GlobalISel for Wasm here upstream, and intend to migrate to -extended-llt ASAP (I would have already if not for this issue). Not much to "migrate" yet, so I wouldn't mind removal of the implicit LLT::integer == LLT::scalar behavior.

But as with most things, I'm sure this compat was done for a highly debated reason, so undoing it so soon seems silly.

@davemgreen davemgreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi - Remove integerExact and emitFloatIEEECxxConstructorCall - this can use the explicit constructors directly (like OS << "LLT(LLT::Kind::INTEGER, ElementCount::getFixed(0), " << Ty.getScalarSizeInBits() << ")";. We might need to change the float calls to generate scalar types eventually too, it is worth adding a FIXME to say that we should clean it up once UseExtended is removed.

You can just update llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td for the test.

OS << "LLT::float128()";
break;
default:
OS << "LLT::floatIEEE(" << SizeInBits << ")";

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this conflicting the function comment which says:

Using specific constructors (float16, float32, etc.) instead of the generic ... floatIEEE()

@DenisGZM

Copy link
Copy Markdown
Contributor

Hi! I think using exact LLT types in generated files is the preferred solution. This is explicit and expected behavior, as the targets themselves enable it. At the same time targets have some space for use scalars and switch them to exact types.

@davemgreen davemgreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that all the types should be using the low level constructors, including float versions. At some point in the future, because we have targets that do not enable ExtendedLLT, the float32() and similar functions might need to generate scalar types too. We can fix this in the future if it comes up though.

if (Ty.isScalar()) {
if (Ty.isInteger())
OS << "LLT::integer(" << Ty.getScalarSizeInBits() << ")";
OS << "LLT(LLT::Kind::INTEGER, ElementCount::getFixed(0), "

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create a lambda that prints the LLT type and reuse it for vector elements too?

EXPECT_TRUE(LLT::scalable_vector(1, 32).isScalableVector());
}

// Demonstrate that LLT::integer() and LLT::floatIEEE() produce different types

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test looks quite AI generated (quite verbose and not of a lot of value). Is it worth keeping or are the existing tests enough to show the issue is fixed? The real test is whether we can select instructions properly, and it hopefully won't be long until we have a real target working in tree.

@davemgreen davemgreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than my comments this LGTM

The GlobalISel uses a lookup table to map LLTs which is constructed
prior to initialization of extended LLT functionality, resulting in
ANY_SCALAR entries. During instruction selection, a hash-based
lookup is done on actual INTEGER/FLOAT LLTs. But hash values of
ANY_SCALAR do not match those of INTEGER/FLOAT, causing a failure.

Workaround is the use constexpr LLT, which encodes INTEGER/FLOAT LLT.

Assisted-by: Claude Opus 4.6
@michalpaszkowski
michalpaszkowski merged commit 2fe82e3 into llvm:main Apr 14, 2026
10 checks passed
@llvm-ci

llvm-ci commented Apr 14, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder sanitizer-x86_64-linux-bootstrap-msan running on sanitizer-buildbot6 while building llvm at step 2 "annotate".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/164/builds/20613

Here is the relevant piece of the build log for the reference
Step 2 (annotate) failure: 'python ../sanitizer_buildbot/sanitizers/zorg/buildbot/builders/sanitizers/buildbot_selector.py' (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using lld-link: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using lld-link: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 98369 tests, 64 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50
FAIL: LLVM :: CodeGen/X86/basic-block-sections-clusters-bb-hash.ll (54408 of 98369)
******************** TEST 'LLVM :: CodeGen/X86/basic-block-sections-clusters-bb-hash.ll' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 11
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -filetype=obj -basic-block-address-map -emit-bb-hash -o /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -filetype=obj -basic-block-address-map -emit-bb-hash -o /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o
# note: command had no output on stdout or stderr
# RUN: at line 16
echo 'v1' > /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo v1
# note: command had no output on stdout or stderr
# RUN: at line 17
echo 'f foo' >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo 'f foo'
# note: command had no output on stdout or stderr
# RUN: at line 18
echo 'g 0:100,1:100,2:0 1:100,3:100 2:0,3:0 3:100' >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo 'g 0:100,1:100,2:0 1:100,3:100 2:0,3:0 3:100'
# note: command had no output on stdout or stderr
# RUN: at line 22
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llvm-readobj /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o --bb-addr-map |  awk 'BEGIN {printf "h"}      /ID: [0-9]+/ {id=$2}      /Hash: 0x[0-9A-Fa-f]+/ {gsub(/^0x/, "", $2); hash=$2; printf " %s:%s", id, hash}      END {print ""}'  >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llvm-readobj /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o --bb-addr-map
# note: command had no output on stdout or stderr
# executed command: awk 'BEGIN {printf "h"}      /ID: [0-9]+/ {id=$2}      /Hash: 0x[0-9A-Fa-f]+/ {gsub(/^0x/, "", $2); hash=$2; printf " %s:%s", id, hash}      END {print ""}'
# note: command had no output on stdout or stderr
# RUN: at line 29
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc < /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1 -basic-block-section-match-infer |  /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/FileCheck /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -check-prefixes=CHECK,LINUX-SECTIONS1
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1 -basic-block-section-match-infer
# note: command had no output on stdout or stderr
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/FileCheck /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -check-prefixes=CHECK,LINUX-SECTIONS1
# .---command stderr------------
# | /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll:80:26: error: LINUX-SECTIONS1-LABEL: expected string not found in input
# | ; LINUX-SECTIONS1-LABEL: # %bb.1:
# |                          ^
# | <stdin>:7:5: note: scanning from here
# | foo: # @foo
Step 11 (stage2/msan check) failure: stage2/msan check (failure)
...
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using lld-link: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using lld-link: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/lld-link
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using ld64.lld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/ld64.lld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/llvm/config.py:569: note: using wasm-ld: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/wasm-ld
llvm-lit: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/utils/lit/lit/main.py:74: note: The test suite configuration requested an individual test timeout of 0 seconds but a timeout of 900 seconds was requested on the command line. Forcing timeout to be 900 seconds.
-- Testing: 98369 tests, 64 workers --
Testing:  0.. 10.. 20.. 30.. 40.. 50
FAIL: LLVM :: CodeGen/X86/basic-block-sections-clusters-bb-hash.ll (54408 of 98369)
******************** TEST 'LLVM :: CodeGen/X86/basic-block-sections-clusters-bb-hash.ll' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 11
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -filetype=obj -basic-block-address-map -emit-bb-hash -o /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -filetype=obj -basic-block-address-map -emit-bb-hash -o /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o
# note: command had no output on stdout or stderr
# RUN: at line 16
echo 'v1' > /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo v1
# note: command had no output on stdout or stderr
# RUN: at line 17
echo 'f foo' >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo 'f foo'
# note: command had no output on stdout or stderr
# RUN: at line 18
echo 'g 0:100,1:100,2:0 1:100,3:100 2:0,3:0 3:100' >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: echo 'g 0:100,1:100,2:0 1:100,3:100 2:0,3:0 3:100'
# note: command had no output on stdout or stderr
# RUN: at line 22
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llvm-readobj /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o --bb-addr-map |  awk 'BEGIN {printf "h"}      /ID: [0-9]+/ {id=$2}      /Hash: 0x[0-9A-Fa-f]+/ {gsub(/^0x/, "", $2); hash=$2; printf " %s:%s", id, hash}      END {print ""}'  >> /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llvm-readobj /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp.o --bb-addr-map
# note: command had no output on stdout or stderr
# executed command: awk 'BEGIN {printf "h"}      /ID: [0-9]+/ {id=$2}      /Hash: 0x[0-9A-Fa-f]+/ {gsub(/^0x/, "", $2); hash=$2; printf " %s:%s", id, hash}      END {print ""}'
# note: command had no output on stdout or stderr
# RUN: at line 29
/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc < /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1 -basic-block-section-match-infer |  /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/FileCheck /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -check-prefixes=CHECK,LINUX-SECTIONS1
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/llc -O0 -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=/home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/test/CodeGen/X86/Output/basic-block-sections-clusters-bb-hash.ll.tmp1 -basic-block-section-match-infer
# note: command had no output on stdout or stderr
# executed command: /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/bin/FileCheck /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll -check-prefixes=CHECK,LINUX-SECTIONS1
# .---command stderr------------
# | /home/b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm-project/llvm/test/CodeGen/X86/basic-block-sections-clusters-bb-hash.ll:80:26: error: LINUX-SECTIONS1-LABEL: expected string not found in input
# | ; LINUX-SECTIONS1-LABEL: # %bb.1:
# |                          ^
# | <stdin>:7:5: note: scanning from here
# | foo: # @foo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants