[clang] [CIR] Implement ExtVectorElementExpr with non simple base (PR #195165)

Amr Hesham via cfe-commits cfe-commits at lists.llvm.org
Sat May 2 00:31:57 PDT 2026


https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/195165

>From f0615e1b4c40291f3d168daa75657661cd8ae0f9 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Thu, 30 Apr 2026 21:00:59 +0200
Subject: [PATCH 1/2] [CIR] Implement ExtVectorElementExpr with non simple base

---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          | 11 ++++++---
 clang/test/CIR/CodeGen/vector-ext-element.cpp | 24 +++++++++++++++++++
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 2959dc567da05..2c2f497e808fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1551,9 +1551,14 @@ LValue CIRGenFunction::emitExtVectorElementExpr(const ExtVectorElementExpr *e) {
                                     base.getBaseInfo());
   }
 
-  cgm.errorNYI(e->getSourceRange(),
-               "emitExtVectorElementExpr: isSimple is false");
-  return {};
+  assert(base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
+  mlir::ArrayAttr baseElts = base.getExtVectorElts();
+  SmallVector<int64_t> elts;
+  for (unsigned idx : indices)
+    elts.push_back(getAccessedFieldNo(idx, baseElts));
+  mlir::ArrayAttr cv = builder.getI64ArrayAttr(elts);
+  return LValue::makeExtVectorElt(base.getAddress(), cv, type,
+                                  base.getBaseInfo());
 }
 
 LValue CIRGenFunction::emitStringLiteralLValue(const StringLiteral *e,
diff --git a/clang/test/CIR/CodeGen/vector-ext-element.cpp b/clang/test/CIR/CodeGen/vector-ext-element.cpp
index 1d071a583f5dc..502e5f2df6324 100644
--- a/clang/test/CIR/CodeGen/vector-ext-element.cpp
+++ b/clang/test/CIR/CodeGen/vector-ext-element.cpp
@@ -402,3 +402,27 @@ void store_src_dest_not_same_size() {
 // OGCG: %[[SHUFFLE_A:.*]] = shufflevector <2 x i32> %[[TMP_B]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
 // OGCG: %[[RESULT:.*]] = shufflevector <4 x i32> %[[TMP_A]], <4 x i32> %[[SHUFFLE_A]], <4 x i32> <i32 4, i32 5, i32 2, i32 3>
 // OGCG: store <4 x i32> %[[RESULT]], ptr %[[A_ADDR]], align 16
+
+void non_simple_base() {
+  vi4 a;
+  int b = a.xy.x;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !s64i
+// CIR: %[[RESULT:.*]] = cir.vec.extract %[[TMP_A]][%[[CONST_0]] : !s64i] : !cir.vector<4 x !s32i>
+// CIR: cir.store {{.*}} %[[RESULT]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: %[[A_ADDR:.*]] = alloca <4 x i32>
+// LLVM: %[[B_ADDR]] = alloca i32
+// LLVM: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
+// LLVM: %[[RESULT:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 0
+// LLVM: store i32 %[[RESULT]], ptr %[[B_ADDR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca <4 x i32>, align 16
+// OGCG: %[[B_ADDR]] = alloca i32, align 4
+// OGCG: %[[TMP_A:.*]] = load <4 x i32>, ptr %[[A_ADDR]], align 16
+// OGCG: %[[RESULT:.*]] = extractelement <4 x i32> %[[TMP_A]], i64 0
+// OGCG: store i32 %[[RESULT]], ptr %[[B_ADDR]], align 4

>From 3941865f8387f43214991ab5ecea49202fb2f682 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Sat, 2 May 2026 09:12:47 +0200
Subject: [PATCH 2/2] Add NYI for MatrixRow

---
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 5 +++++
 clang/lib/CIR/CodeGen/CIRGenValue.h  | 4 +++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 2c2f497e808fc..cb53430438219 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1551,6 +1551,11 @@ LValue CIRGenFunction::emitExtVectorElementExpr(const ExtVectorElementExpr *e) {
                                     base.getBaseInfo());
   }
 
+  if (base.isMatrixRow()) {
+    cgm.errorNYI(e->getSourceRange(), "emitExtVectorElementExpr: isMatrixRow");
+    return {};
+  }
+
   assert(base.isExtVectorElt() && "Can only subscript lvalue vec elts here!");
   mlir::ArrayAttr baseElts = base.getExtVectorElts();
   SmallVector<int64_t> elts;
diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h
index e1bbc54cfb9b1..e70dac5851189 100644
--- a/clang/lib/CIR/CodeGen/CIRGenValue.h
+++ b/clang/lib/CIR/CodeGen/CIRGenValue.h
@@ -158,7 +158,8 @@ class LValue {
     BitField,     // This is a bitfield l-value, use getBitfield*.
     ExtVectorElt, // This is an extended vector subset, use getExtVectorComp
     GlobalReg,    // This is a register l-value, use getGlobalReg()
-    MatrixElt     // This is a matrix element, use getVector*
+    MatrixElt,    // This is a matrix element, use getVector*
+    MatrixRow     // This is a matrix vector subset, use getVector*
   } lvType;
   clang::QualType type;
   clang::Qualifiers quals;
@@ -194,6 +195,7 @@ class LValue {
   bool isBitField() const { return lvType == BitField; }
   bool isExtVectorElt() const { return lvType == ExtVectorElt; }
   bool isGlobalReg() const { return lvType == GlobalReg; }
+  bool isMatrixRow() const { return lvType == MatrixRow; }
   bool isVolatile() const { return quals.hasVolatile(); }
 
   bool isVolatileQualified() const { return quals.hasVolatile(); }



More information about the cfe-commits mailing list