[clang] [CIR] Support x86 encodeKey builtins (PR #179308)
Omar Hossam via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 6 09:50:57 PST 2026
https://github.com/moar55 updated https://github.com/llvm/llvm-project/pull/179308
>From a801ec8c930309e25b01955adf48ceababe00631 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Mon, 2 Feb 2026 19:59:54 +0100
Subject: [PATCH 1/7] [CIR] Support x86 builtin rotate
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 53 +++++-
.../X86/key-locker-encodekey.c | 166 ++++++++++++++++++
2 files changed, 214 insertions(+), 5 deletions(-)
create mode 100644 clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 80022998448ad..d7204fba98a3b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -15,17 +15,29 @@
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "mlir/IR/Attributes.h"
+#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Location.h"
+#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Types.h"
+#include "mlir/IR/Value.h"
#include "mlir/IR/ValueRange.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/TypeBase.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cstddef>
+#include <numeric>
#include <string>
using namespace clang;
@@ -186,6 +198,33 @@ static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder,
mlir::ValueRange{source, mask, maskValue});
}
+static mlir::Value
+emitEncodeKey(mlir::MLIRContext *context, CIRGenBuilderTy &builder,
+ const mlir::Location &location, mlir::ValueRange inputOperands,
+ mlir::Value &outputOperand, std::uint8_t vecOutputCount,
+ const std::string &intrinsicName) {
+ cir::VectorType resVector = cir::VectorType::get(builder.getUInt64Ty(), 2);
+ auto membersRng = llvm::concat<mlir::Type>(
+ llvm::SmallVector<mlir::Type>{builder.getUInt32Ty()},
+ llvm::SmallVector<mlir::Type>(vecOutputCount, resVector));
+ cir::RecordType resRecord =
+ cir::RecordType::get(context, llvm::to_vector(membersRng), false, false,
+ cir::RecordType::RecordKind::Struct);
+
+ mlir::Value outputPtr =
+ builder.createBitcast(outputOperand, cir::PointerType::get(resVector));
+ mlir::Value call = emitIntrinsicCallOp(builder, location, intrinsicName,
+ resRecord, inputOperands);
+ for (std::size_t i = 0; i < inputOperands.size() + 1; ++i) {
+ mlir::Value vecValue =
+ cir::ExtractMemberOp::create(builder, location, call, i + 1);
+ mlir::Value index = builder.getSInt32(i, location);
+ mlir::Value ptr = builder.createPtrStride(location, outputPtr, index);
+ builder.createStore(location, vecValue, Address{ptr, CharUnits::One()});
+ }
+ return cir::ExtractMemberOp::create(builder, location, call, 0);
+}
+
static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
mlir::Value mask, mlir::Value op0,
mlir::Value op1) {
@@ -2403,13 +2442,17 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
case X86::BI__readgsword:
case X86::BI__readgsdword:
case X86::BI__readgsqword:
- case X86::BI__builtin_ia32_encodekey128_u32:
+ case X86::BI__builtin_ia32_encodekey128_u32: {
+ return emitEncodeKey(&getMLIRContext(), builder, getLoc(expr->getExprLoc()),
+ {ops[0], ops[1]}, ops[2], 6, "x86.encodekey128");
+ }
case X86::BI__builtin_ia32_encodekey256_u32: {
- cgm.errorNYI(expr->getSourceRange(),
- std::string("unimplemented X86 builtin call: ") +
- getContext().BuiltinInfo.getName(builtinID));
- return mlir::Value{};
+
+ return emitEncodeKey(&getMLIRContext(), builder, getLoc(expr->getExprLoc()),
+ {ops[0], ops[1], ops[2]}, ops[3], 7,
+ "x86.encodekey256");
}
+
case X86::BI__builtin_ia32_aesenc128kl_u8:
case X86::BI__builtin_ia32_aesdec128kl_u8:
case X86::BI__builtin_ia32_aesenc256kl_u8:
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c b/clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c
new file mode 100644
index 0000000000000..4ddf91ca4a0ab
--- /dev/null
+++ b/clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c
@@ -0,0 +1,166 @@
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -emit-cir -o %t.cir -Wall -Werror
+// RUN: FileCheck --check-prefixes=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -emit-cir -o %t.cir -Wall -Werror
+// RUN: FileCheck --check-prefixes=CIR --input-file=%t.cir %s
+
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -fclangir -emit-llvm -o %t.ll -Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -fclangir -emit-llvm -o %t.ll -Wall -Werror
+// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
+
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG
+// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG
+
+#include <x86intrin.h>
+
+// CIR: !rec_anon_struct = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
+// CIR: !rec_anon_struct1 = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
+
+unsigned int test_encodekey128_u32(unsigned int htype, __m128i key, void *h) {
+ // CIR-LABEL: _mm_encodekey128_u32
+ // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey128" {{.*}} : (!u32i, !cir.vector<2 x !s64i>) -> !rec_anon_struct
+
+ // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct -> !cir.vector<2 x !u64i>
+ // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
+ // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct -> !cir.vector<2 x !u64i>
+ // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
+ // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct -> !cir.vector<2 x !u64i>
+ // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
+ // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct -> !u32i
+ // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
+ // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
+ // CIR: cir.return %[[RET]] : !u32i
+
+ // LLVM-LABEL: test_encodekey128_u32
+ // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
+
+ // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
+
+ // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // LLVM: store i32 %[[RET_EXT]], ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
+ // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
+ // LLVM: ret i32 %[[RET]]
+
+ // OGCG-LABEL: @test_encodekey128_u32
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8}}
+ // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
+
+ // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
+
+ // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // OGCG: %[[RET:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // OGCG: ret i32 %[[RET]]
+ return _mm_encodekey128_u32(htype, key, h);
+}
+
+unsigned int test_encodekey256_u32(unsigned int htype, __m128i key_lo,
+ __m128i key_hi, void *h) {
+ // CIR-LABEL: _mm_encodekey256_u32
+ // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey256" {{.*}} : (!u32i, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>) -> !rec_anon_struct1
+
+ // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
+ // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
+ // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
+ // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X3:.*]] = cir.extract_member %[[CALL]][4] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C3:.*]] = cir.const #cir.int<3> : !s32i
+ // CIR: %[[P3:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C3]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X3]], %[[P3]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct1 -> !u32i
+ // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
+ // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
+ // CIR: cir.return %[[RET]] : !u32i
+
+ // LLVM-LABEL: test_encodekey256_u32
+ // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+ // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
+
+ // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // LLVM: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
+ // LLVM: %[[P3:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 3
+ // LLVM: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
+
+ // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // LLVM: store i32 %[[RET_EXT]], ptr [[RET_PTR1:.*]], align 4
+ // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
+ // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
+ // LLVM: ret i32 %[[RET]]
+
+ // OGCG-LABEL: @test_encodekey256_u32
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8|16}}
+ // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+ // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
+
+ // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // OGCG: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
+ // OGCG: %[[P3:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 48
+ // OGCG: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
+
+ // OGCG: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // OGCG: ret i32 %[[RET_EXT]]
+
+ return _mm_encodekey256_u32(htype, key_lo, key_hi, h);
+}
>From 28bd644fe2dababf91fa5c336ced00175d3261e1 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Mon, 2 Feb 2026 20:29:50 +0100
Subject: [PATCH 2/7] bug fix
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index d7204fba98a3b..fb267680eddb4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -201,20 +201,19 @@ static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder,
static mlir::Value
emitEncodeKey(mlir::MLIRContext *context, CIRGenBuilderTy &builder,
const mlir::Location &location, mlir::ValueRange inputOperands,
- mlir::Value &outputOperand, std::uint8_t vecOutputCount,
+ mlir::Value outputOperand, std::uint8_t vecOutputCount,
const std::string &intrinsicName) {
cir::VectorType resVector = cir::VectorType::get(builder.getUInt64Ty(), 2);
- auto membersRng = llvm::concat<mlir::Type>(
- llvm::SmallVector<mlir::Type>{builder.getUInt32Ty()},
- llvm::SmallVector<mlir::Type>(vecOutputCount, resVector));
- cir::RecordType resRecord =
- cir::RecordType::get(context, llvm::to_vector(membersRng), false, false,
- cir::RecordType::RecordKind::Struct);
+ llvm::SmallVector<mlir::Type> members{builder.getUInt32Ty()};
+ llvm::append_range(members,
+ llvm::SmallVector<mlir::Type>(vecOutputCount, resVector));
+ cir::RecordType resRecord = cir::RecordType::get(
+ context, members, false, false, cir::RecordType::RecordKind::Struct);
mlir::Value outputPtr =
builder.createBitcast(outputOperand, cir::PointerType::get(resVector));
- mlir::Value call = emitIntrinsicCallOp(builder, location, intrinsicName,
- resRecord, inputOperands);
+ mlir::Value call = builder.emitIntrinsicCallOp(location, intrinsicName,
+ resRecord, inputOperands);
for (std::size_t i = 0; i < inputOperands.size() + 1; ++i) {
mlir::Value vecValue =
cir::ExtractMemberOp::create(builder, location, call, i + 1);
>From 909d4dd005adccb19d438491feba9fc0905833a2 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Mon, 2 Feb 2026 20:31:26 +0100
Subject: [PATCH 3/7] match original codegen test name
---
.../CodeGenBuiltins/X86/{key-locker-encodekey.c => key-locker.c} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename clang/test/CIR/CodeGenBuiltins/X86/{key-locker-encodekey.c => key-locker.c} (100%)
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c b/clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
similarity index 100%
rename from clang/test/CIR/CodeGenBuiltins/X86/key-locker-encodekey.c
rename to clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
>From 43403a7a63836726a63ff92a3dec68396b52b248 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Mon, 2 Feb 2026 21:12:14 +0100
Subject: [PATCH 4/7] merge into keylocker.c
---
.../test/CIR/CodeGenBuiltins/X86/keylocker.c | 151 ++++++++++++++++++
1 file changed, 151 insertions(+)
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c b/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
index a4995a108c8c8..de65924d588ad 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
@@ -18,6 +18,8 @@
// CIR: !rec_anon_struct = !cir.record<struct {!u8i, !cir.vector<2 x !s64i>}>
// CIR: !rec_anon_struct1 = !cir.record<struct {!u8i, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>}>
+// CIR: !rec_anon_struct2 = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
+// CIR: !rec_anon_struct3 = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
unsigned char test_mm_aesenc256kl_u8(__m128i *odata, __m128i idata, const void *h) {
// CIR-LABEL: _mm_aesenc256kl_u8
@@ -1174,3 +1176,152 @@ unsigned char test__mm_aesdecwide128kl_u8(__m128i odata[8], const __m128i idata[
// OGCG: ret i8 %[[RET]]
return _mm_aesdecwide128kl_u8(odata, idata, h);
}
+
+unsigned int test_encodekey128_u32(unsigned int htype, __m128i key, void *h) {
+ // CIR-LABEL: _mm_encodekey128_u32
+ // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey128" {{.*}} : (!u32i, !cir.vector<2 x !s64i>) -> !rec_anon_struct2
+
+ // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct2 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
+ // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct2 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
+ // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct2 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
+ // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct2 -> !u32i
+ // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
+ // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
+ // CIR: cir.return %[[RET]] : !u32i
+
+ // LLVM-LABEL: test_encodekey128_u32
+ // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
+
+ // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
+
+ // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // LLVM: store i32 %[[RET_EXT]], ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
+ // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
+ // LLVM: ret i32 %[[RET]]
+
+ // OGCG-LABEL: test_encodekey128_u32
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8}}
+ // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
+
+ // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
+
+ // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // OGCG: %[[RET:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // OGCG: ret i32 %[[RET]]
+ return _mm_encodekey128_u32(htype, key, h);
+}
+
+unsigned int test_encodekey256_u32(unsigned int htype, __m128i key_lo,
+ __m128i key_hi, void *h) {
+ // CIR-LABEL: _mm_encodekey256_u32
+ // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
+ // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey256" {{.*}} : (!u32i, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>) -> !rec_anon_struct3
+
+ // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct3 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
+ // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct3 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
+ // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct3 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
+ // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[X3:.*]] = cir.extract_member %[[CALL]][4] : !rec_anon_struct3 -> !cir.vector<2 x !u64i>
+ // CIR: %[[C3:.*]] = cir.const #cir.int<3> : !s32i
+ // CIR: %[[P3:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C3]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
+ // CIR: cir.store align(1) %[[X3]], %[[P3]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
+
+ // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct3 -> !u32i
+ // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
+ // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
+ // CIR: cir.return %[[RET]] : !u32i
+
+ // LLVM-LABEL: test_encodekey256_u32
+ // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+ // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
+
+ // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // LLVM: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
+ // LLVM: %[[P3:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 3
+ // LLVM: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
+
+ // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // LLVM: store i32 %[[RET_EXT]], ptr [[RET_PTR1:.*]], align 4
+ // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
+ // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
+ // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
+ // LLVM: ret i32 %[[RET]]
+
+ // OGCG-LABEL: test_encodekey256_u32
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8|16}}
+ // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
+
+ // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
+ // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
+
+ // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
+
+ // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
+
+ // OGCG: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
+ // OGCG: %[[P3:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 48
+ // OGCG: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
+
+ // OGCG: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
+ // OGCG: ret i32 %[[RET_EXT]]
+
+ return _mm_encodekey256_u32(htype, key_lo, key_hi, h);
+}
>From 3acd83563b8410e2b39f558699344d214ced5900 Mon Sep 17 00:00:00 2001
From: Omar Hossam <moar.ahmed at gmail.com>
Date: Mon, 2 Feb 2026 21:17:16 +0100
Subject: [PATCH 5/7] Delete clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
remove leftover file
---
.../test/CIR/CodeGenBuiltins/X86/key-locker.c | 166 ------------------
1 file changed, 166 deletions(-)
delete mode 100644 clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/key-locker.c b/clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
deleted file mode 100644
index 4ddf91ca4a0ab..0000000000000
--- a/clang/test/CIR/CodeGenBuiltins/X86/key-locker.c
+++ /dev/null
@@ -1,166 +0,0 @@
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -emit-cir -o %t.cir -Wall -Werror
-// RUN: FileCheck --check-prefixes=CIR --input-file=%t.cir %s
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -emit-cir -o %t.cir -Wall -Werror
-// RUN: FileCheck --check-prefixes=CIR --input-file=%t.cir %s
-
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -fclangir -emit-llvm -o %t.ll -Wall -Werror
-// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -fclangir -emit-llvm -o %t.ll -Wall -Werror
-// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
-
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=x86_64-unknown-unknown -target-feature +kl -target-feature +widekl -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG
-// RUN: %clang_cc1 %s -O0 -ffreestanding -triple=i386-unknown-unknown -target-feature +kl -target-feature +widekl -emit-llvm -o - -Wall -Werror | FileCheck %s --check-prefixes=OGCG
-
-#include <x86intrin.h>
-
-// CIR: !rec_anon_struct = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
-// CIR: !rec_anon_struct1 = !cir.record<struct {!u32i, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>, !cir.vector<2 x !u64i>}>
-
-unsigned int test_encodekey128_u32(unsigned int htype, __m128i key, void *h) {
- // CIR-LABEL: _mm_encodekey128_u32
- // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
- // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey128" {{.*}} : (!u32i, !cir.vector<2 x !s64i>) -> !rec_anon_struct
-
- // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct -> !cir.vector<2 x !u64i>
- // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
- // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct -> !cir.vector<2 x !u64i>
- // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
- // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct -> !cir.vector<2 x !u64i>
- // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
- // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct -> !u32i
- // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
- // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
- // CIR: cir.return %[[RET]] : !u32i
-
- // LLVM-LABEL: test_encodekey128_u32
- // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
-
- // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
- // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
-
- // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
- // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
-
- // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
- // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
-
- // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
- // LLVM: store i32 %[[RET_EXT]], ptr %[[RET_PTR1:.*]], align 4
- // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
- // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
- // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
- // LLVM: ret i32 %[[RET]]
-
- // OGCG-LABEL: @test_encodekey128_u32
- // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8}}
- // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
-
- // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
- // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
-
- // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
- // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
-
- // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
- // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
-
- // OGCG: %[[RET:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
- // OGCG: ret i32 %[[RET]]
- return _mm_encodekey128_u32(htype, key, h);
-}
-
-unsigned int test_encodekey256_u32(unsigned int htype, __m128i key_lo,
- __m128i key_hi, void *h) {
- // CIR-LABEL: _mm_encodekey256_u32
- // CIR: %[[H:.*]] = cir.load {{.*}} : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
- // CIR: %[[OUT_PTR:.*]] = cir.cast bitcast %[[H]] : !cir.ptr<!void> -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: %[[CALL:.*]] = cir.call_llvm_intrinsic "x86.encodekey256" {{.*}} : (!u32i, !cir.vector<2 x !s64i>, !cir.vector<2 x !s64i>) -> !rec_anon_struct1
-
- // CIR: %[[X0:.*]] = cir.extract_member %[[CALL]][1] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
- // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !s32i
- // CIR: %[[P0:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C0]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X0]], %[[P0]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[X1:.*]] = cir.extract_member %[[CALL]][2] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
- // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
- // CIR: %[[P1:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C1]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X1]], %[[P1]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[X2:.*]] = cir.extract_member %[[CALL]][3] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
- // CIR: %[[C2:.*]] = cir.const #cir.int<2> : !s32i
- // CIR: %[[P2:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C2]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X2]], %[[P2]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[X3:.*]] = cir.extract_member %[[CALL]][4] : !rec_anon_struct1 -> !cir.vector<2 x !u64i>
- // CIR: %[[C3:.*]] = cir.const #cir.int<3> : !s32i
- // CIR: %[[P3:.*]] = cir.ptr_stride %[[OUT_PTR]], %[[C3]] : (!cir.ptr<!cir.vector<2 x !u64i>>, !s32i) -> !cir.ptr<!cir.vector<2 x !u64i>>
- // CIR: cir.store align(1) %[[X3]], %[[P3]] : !cir.vector<2 x !u64i>, !cir.ptr<!cir.vector<2 x !u64i>>
-
- // CIR: %[[RET_EXT:.*]] = cir.extract_member %[[CALL]][0] : !rec_anon_struct1 -> !u32i
- // CIR: cir.store %[[RET_EXT]], %[[RET_PTR:.*]] : !u32i, !cir.ptr<!u32i>
- // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i
- // CIR: cir.return %[[RET]] : !u32i
-
- // LLVM-LABEL: test_encodekey256_u32
- // LLVM: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-
- // LLVM: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
- // LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
-
- // LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
- // LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
-
- // LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
- // LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
-
- // LLVM: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
- // LLVM: %[[P3:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 3
- // LLVM: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
-
- // LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
- // LLVM: store i32 %[[RET_EXT]], ptr [[RET_PTR1:.*]], align 4
- // LLVM: %[[RET1:.*]] = load i32, ptr %[[RET_PTR1:.*]], align 4
- // LLVM: store i32 %[[RET1]], ptr %[[RET_PTR:.*]], align 4
- // LLVM: %[[RET:.*]] = load i32, ptr %[[RET_PTR]], align 4
- // LLVM: ret i32 %[[RET]]
-
- // OGCG-LABEL: @test_encodekey256_u32
- // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8|16}}
- // OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
-
- // OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
- // OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
-
- // OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
- // OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
-
- // OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
- // OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
-
- // OGCG: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
- // OGCG: %[[P3:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 48
- // OGCG: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
-
- // OGCG: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
- // OGCG: ret i32 %[[RET_EXT]]
-
- return _mm_encodekey256_u32(htype, key_lo, key_hi, h);
-}
>From 0d1f890e00410aef70adbfd24901ae7f38fc8808 Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Tue, 3 Feb 2026 22:26:30 +0100
Subject: [PATCH 6/7] address comments, rebase
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 27 +++++++------------
.../test/CIR/CodeGenBuiltins/X86/keylocker.c | 24 ++++++++---------
2 files changed, 22 insertions(+), 29 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index fb267680eddb4..25d7bb45d1b17 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -15,29 +15,17 @@
#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "mlir/IR/Attributes.h"
-#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/Location.h"
-#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/Types.h"
-#include "mlir/IR/Value.h"
#include "mlir/IR/ValueRange.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/TypeBase.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
-#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/MissingFeatures.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
-#include <cstddef>
-#include <numeric>
#include <string>
using namespace clang;
@@ -202,7 +190,7 @@ static mlir::Value
emitEncodeKey(mlir::MLIRContext *context, CIRGenBuilderTy &builder,
const mlir::Location &location, mlir::ValueRange inputOperands,
mlir::Value outputOperand, std::uint8_t vecOutputCount,
- const std::string &intrinsicName) {
+ const std::string &intrinsicName, std::uint8_t numResults) {
cir::VectorType resVector = cir::VectorType::get(builder.getUInt64Ty(), 2);
llvm::SmallVector<mlir::Type> members{builder.getUInt32Ty()};
llvm::append_range(members,
@@ -214,7 +202,7 @@ emitEncodeKey(mlir::MLIRContext *context, CIRGenBuilderTy &builder,
builder.createBitcast(outputOperand, cir::PointerType::get(resVector));
mlir::Value call = builder.emitIntrinsicCallOp(location, intrinsicName,
resRecord, inputOperands);
- for (std::size_t i = 0; i < inputOperands.size() + 1; ++i) {
+ for (std::uint8_t i = 0; i < numResults; ++i) {
mlir::Value vecValue =
cir::ExtractMemberOp::create(builder, location, call, i + 1);
mlir::Value index = builder.getSInt32(i, location);
@@ -2439,17 +2427,22 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
case X86::BI__readfsqword:
case X86::BI__readgsbyte:
case X86::BI__readgsword:
- case X86::BI__readgsdword:
+ case X86::BI__readgsdword: {
+ cgm.errorNYI(expr->getSourceRange(),
+ std::string("unimplemented X86 builtin call: ") +
+ getContext().BuiltinInfo.getName(builtinID));
+ return mlir::Value{};
+ }
case X86::BI__readgsqword:
case X86::BI__builtin_ia32_encodekey128_u32: {
return emitEncodeKey(&getMLIRContext(), builder, getLoc(expr->getExprLoc()),
- {ops[0], ops[1]}, ops[2], 6, "x86.encodekey128");
+ {ops[0], ops[1]}, ops[2], 6, "x86.encodekey128", 3);
}
case X86::BI__builtin_ia32_encodekey256_u32: {
return emitEncodeKey(&getMLIRContext(), builder, getLoc(expr->getExprLoc()),
{ops[0], ops[1], ops[2]}, ops[3], 7,
- "x86.encodekey256");
+ "x86.encodekey256", 4);
}
case X86::BI__builtin_ia32_aesenc128kl_u8:
diff --git a/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c b/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
index de65924d588ad..6f4512c813820 100644
--- a/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
+++ b/clang/test/CIR/CodeGenBuiltins/X86/keylocker.c
@@ -1210,11 +1210,11 @@ unsigned int test_encodekey128_u32(unsigned int htype, __m128i key, void *h) {
// LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
// LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i64 1
// LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
// LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i64 2
// LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
// LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
@@ -1225,18 +1225,18 @@ unsigned int test_encodekey128_u32(unsigned int htype, __m128i key, void *h) {
// LLVM: ret i32 %[[RET]]
// OGCG-LABEL: test_encodekey128_u32
- // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8}}
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align 8
// OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey128(i32 %{{.*}}, <2 x i64> %{{.*}})
// OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
// OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
// OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i32 16
// OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
// OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i32 32
// OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
// OGCG: %[[RET:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
@@ -1283,15 +1283,15 @@ unsigned int test_encodekey256_u32(unsigned int htype, __m128i key_lo,
// LLVM: store <2 x i64> %[[X0]], ptr %[[OUT_PTR:.*]], align 1
// LLVM: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 1
+ // LLVM: %[[P1:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i64 1
// LLVM: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
// LLVM: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 2
+ // LLVM: %[[P2:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i64 2
// LLVM: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
// LLVM: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
- // LLVM: %[[P3:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i{{32|64}} 3
+ // LLVM: %[[P3:.*]] = getelementptr <2 x i64>, ptr %[[OUT_PTR]], i64 3
// LLVM: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
// LLVM: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
@@ -1302,22 +1302,22 @@ unsigned int test_encodekey256_u32(unsigned int htype, __m128i key_lo,
// LLVM: ret i32 %[[RET]]
// OGCG-LABEL: test_encodekey256_u32
- // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align {{4|8|16}}
+ // OGCG: %[[OUT_PTR:.*]] = load ptr, ptr %__h.addr.i, align 8
// OGCG: %[[CALL:.*]] = call { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } @llvm.x86.encodekey256(i32 %{{.*}}, <2 x i64> %{{.*}}, <2 x i64> %{{.*}})
// OGCG: %[[X0:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 1
// OGCG: store <2 x i64> %[[X0]], ptr %[[OUT_PTR]], align 1
// OGCG: %[[X1:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 2
- // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 16
+ // OGCG: %[[P1:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i32 16
// OGCG: store <2 x i64> %[[X1]], ptr %[[P1]], align 1
// OGCG: %[[X2:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 3
- // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 32
+ // OGCG: %[[P2:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i32 32
// OGCG: store <2 x i64> %[[X2]], ptr %[[P2]], align 1
// OGCG: %[[X3:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 4
- // OGCG: %[[P3:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i{{32|64}} 48
+ // OGCG: %[[P3:.*]] = getelementptr i8, ptr %[[OUT_PTR]], i32 48
// OGCG: store <2 x i64> %[[X3]], ptr %[[P3]], align 1
// OGCG: %[[RET_EXT:.*]] = extractvalue { i32, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64>, <2 x i64> } %[[CALL]], 0
>From 638547aae86ce048ad70c4a852d4de8960d1cd7e Mon Sep 17 00:00:00 2001
From: Omar Ibrahim <moar.ahmed at gmail.com>
Date: Fri, 6 Feb 2026 18:49:04 +0100
Subject: [PATCH 7/7] address comment
---
clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
index 25d7bb45d1b17..cad80317cb870 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp
@@ -2427,13 +2427,13 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) {
case X86::BI__readfsqword:
case X86::BI__readgsbyte:
case X86::BI__readgsword:
- case X86::BI__readgsdword: {
+ case X86::BI__readgsdword:
+ case X86::BI__readgsqword: {
cgm.errorNYI(expr->getSourceRange(),
std::string("unimplemented X86 builtin call: ") +
getContext().BuiltinInfo.getName(builtinID));
return mlir::Value{};
}
- case X86::BI__readgsqword:
case X86::BI__builtin_ia32_encodekey128_u32: {
return emitEncodeKey(&getMLIRContext(), builder, getLoc(expr->getExprLoc()),
{ops[0], ops[1]}, ops[2], 6, "x86.encodekey128", 3);
More information about the cfe-commits
mailing list