[clang] [CIR] Use the AST result type for sizeof/alignof constants (PR #203942)

Akshay K via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 16 07:38:20 PDT 2026


https://github.com/kumarak updated https://github.com/llvm/llvm-project/pull/203942

>From b0aa7b3a29049d6e4f81e8e38bece4b8b07acb24 Mon Sep 17 00:00:00 2001
From: AkshayK <iit.akshay at gmail.com>
Date: Mon, 15 Jun 2026 11:47:33 -0400
Subject: [PATCH 1/2] [CIR] Use the AST result type for sizeof/alignof
 constants

The constant was built with a hardcoded 64-bit type, mismatching the
APInt width from EvaluateKnownConstInt on targets where size_t is
narrower (e.g. i686) and tripping the IntAttr verifier. Emit it with
cgf.cgm.sizeTy instead, matching classic codegen.
---
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    |  8 ++--
 .../unary-expr-or-type-trait-32bit.cpp        | 47 +++++++++++++++++++
 2 files changed, 52 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index d8b7fa062b845..246f3810e83d1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -2766,16 +2766,18 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr(
           e->getSourceRange(),
           "VisitUnaryExprOrTypeTraitExpr: sizeOf scalable vector");
       return builder.getConstant(
-          loc, cir::IntAttr::get(cgf.cgm.uInt64Ty,
+          loc, cir::IntAttr::get(cgf.cgm.sizeTy,
                                  e->EvaluateKnownConstInt(cgf.getContext())));
     }
 
     return builder.getConstant(
-        loc, cir::IntAttr::get(cgf.cgm.uInt64Ty, vecTy.getSize()));
+        loc, cir::IntAttr::get(cgf.cgm.sizeTy, vecTy.getSize()));
   }
 
+  // The result type is size_t (target-dependent width); use it so the IntAttr
+  // width matches the APInt from EvaluateKnownConstInt.
   return builder.getConstant(
-      loc, cir::IntAttr::get(cgf.cgm.uInt64Ty,
+      loc, cir::IntAttr::get(cgf.cgm.sizeTy,
                              e->EvaluateKnownConstInt(cgf.getContext())));
 }
 
diff --git a/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp b/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp
new file mode 100644
index 0000000000000..7e7cee2a14fe3
--- /dev/null
+++ b/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++20 -triple i686-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -triple i686-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -triple i686-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+
+// The result of sizeof/alignof/__builtin_vectorelements is size_t, which is
+// 32 bits wide on this target. The emitted constants must use that width
+// rather than a hardcoded 64-bit type.
+
+using size_t = decltype(sizeof(int));
+
+size_t size_of_int() { return sizeof(int); }
+
+// CIR-LABEL: cir.func {{.*}}@_Z11size_of_intv() -> !u32i
+// CIR:         cir.const #cir.int<4> : !u32i
+
+// LLVM-LABEL: define {{.*}}i32 @_Z11size_of_intv()
+// LLVM:         store i32 4, ptr
+
+// OGCG-LABEL: define {{.*}}i32 @_Z11size_of_intv()
+// OGCG:         ret i32 4
+
+size_t align_of_double() { return alignof(double); }
+
+// CIR-LABEL: cir.func {{.*}}@_Z15align_of_doublev() -> !u32i
+// CIR:         cir.const #cir.int<4> : !u32i
+
+// LLVM-LABEL: define {{.*}}i32 @_Z15align_of_doublev()
+// LLVM:         store i32 4, ptr
+
+// OGCG-LABEL: define {{.*}}i32 @_Z15align_of_doublev()
+// OGCG:         ret i32 4
+
+typedef int vi4 __attribute__((vector_size(16)));
+
+size_t vector_elements(vi4 v) { return __builtin_vectorelements(v); }
+
+// CIR-LABEL: cir.func {{.*}}@_Z15vector_elementsDv4_i({{.*}}) -> !u32i
+// CIR:         cir.const #cir.int<4> : !u32i
+
+// LLVM-LABEL: define {{.*}}i32 @_Z15vector_elementsDv4_i
+// LLVM:         store i32 4, ptr
+
+// OGCG-LABEL: define {{.*}}i32 @_Z15vector_elementsDv4_i
+// OGCG:         ret i32 4

>From a27eab489705dc67f16d0430f459c24fb7da4b83 Mon Sep 17 00:00:00 2001
From: AkshayK <iit.akshay at gmail.com>
Date: Tue, 16 Jun 2026 10:19:45 -0400
Subject: [PATCH 2/2] [CIR] Merge LLVM/OGCG checks in sizeof 32-bit test

---
 .../unary-expr-or-type-trait-32bit.cpp        | 23 ++++++-------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp b/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp
index 7e7cee2a14fe3..e24278c09e622 100644
--- a/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp
+++ b/clang/test/CIR/CodeGen/unary-expr-or-type-trait-32bit.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang_cc1 -std=c++20 -triple i686-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
 // RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=LLVM
 // RUN: %clang_cc1 -std=c++20 -triple i686-unknown-linux-gnu -emit-llvm %s -o %t.ll
-// RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG
+// RUN: FileCheck --input-file=%t.ll %s --check-prefix=LLVM
 
 // The result of sizeof/alignof/__builtin_vectorelements is size_t, which is
 // 32 bits wide on this target. The emitted constants must use that width
@@ -13,35 +13,26 @@ using size_t = decltype(sizeof(int));
 
 size_t size_of_int() { return sizeof(int); }
 
-// CIR-LABEL: cir.func {{.*}}@_Z11size_of_intv() -> !u32i
+// CIR-LABEL: cir.func {{.*}}@_Z11size_of_intv() -> {{.*}}!u32i
 // CIR:         cir.const #cir.int<4> : !u32i
 
 // LLVM-LABEL: define {{.*}}i32 @_Z11size_of_intv()
-// LLVM:         store i32 4, ptr
-
-// OGCG-LABEL: define {{.*}}i32 @_Z11size_of_intv()
-// OGCG:         ret i32 4
+// LLVM:         {{.*}}i32 4
 
 size_t align_of_double() { return alignof(double); }
 
-// CIR-LABEL: cir.func {{.*}}@_Z15align_of_doublev() -> !u32i
+// CIR-LABEL: cir.func {{.*}}@_Z15align_of_doublev() -> {{.*}}!u32i
 // CIR:         cir.const #cir.int<4> : !u32i
 
 // LLVM-LABEL: define {{.*}}i32 @_Z15align_of_doublev()
-// LLVM:         store i32 4, ptr
-
-// OGCG-LABEL: define {{.*}}i32 @_Z15align_of_doublev()
-// OGCG:         ret i32 4
+// LLVM:         {{.*}}i32 4
 
 typedef int vi4 __attribute__((vector_size(16)));
 
 size_t vector_elements(vi4 v) { return __builtin_vectorelements(v); }
 
-// CIR-LABEL: cir.func {{.*}}@_Z15vector_elementsDv4_i({{.*}}) -> !u32i
+// CIR-LABEL: cir.func {{.*}}@_Z15vector_elementsDv4_i({{.*}}) -> {{.*}}!u32i
 // CIR:         cir.const #cir.int<4> : !u32i
 
 // LLVM-LABEL: define {{.*}}i32 @_Z15vector_elementsDv4_i
-// LLVM:         store i32 4, ptr
-
-// OGCG-LABEL: define {{.*}}i32 @_Z15vector_elementsDv4_i
-// OGCG:         ret i32 4
+// LLVM:         {{.*}}i32 4



More information about the cfe-commits mailing list