https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/138413
>From d0a6c4fa94d387d8c9afec10deae150d6bce54ee Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 3 May 2025 13:43:04 +0200 Subject: [PATCH 1/3] [CIR] Upstream extract op for VectorType --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 24 ++++++++++++++ clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 7 ++-- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 11 ++++++- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 10 ++++++ clang/test/CIR/CodeGen/vector-ext.cpp | 33 +++++++++++++++++++ clang/test/CIR/CodeGen/vector.cpp | 33 +++++++++++++++++++ clang/test/CIR/IR/vector.cir | 32 ++++++++++++++++++ 7 files changed, 147 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 422c89c4f9391..b2121dee8d8b3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1976,4 +1976,28 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> { let hasVerifier = 1; } +//===----------------------------------------------------------------------===// +// VecExtractOp +//===----------------------------------------------------------------------===// + +def VecExtractOp : CIR_Op<"vec.extract", [Pure, + TypesMatchWith<"type of 'result' matches element type of 'vec'", "vec", + "result", "cast<VectorType>($_self).getElementType()">]> { + + let summary = "Extract one element from a vector object"; + let description = [{ + The `cir.vec.extract` operation extracts the element at the given index + from a vector object. + }]; + + let arguments = (ins CIR_VectorType:$vec, CIR_AnyFundamentalIntType:$index); + let results = (outs CIR_AnyType:$result); + + let assemblyFormat = [{ + $vec `[` $index `:` type($index) `]` attr-dict `:` qualified(type($vec)) + }]; + + let hasVerifier = 0; +} + #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 8ead6e793b4c8..a59b87cb9241b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -161,8 +161,11 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitArraySubscriptExpr(ArraySubscriptExpr *e) { if (e->getBase()->getType()->isVectorType()) { assert(!cir::MissingFeatures::scalableVectors()); - cgf.getCIRGenModule().errorNYI("VisitArraySubscriptExpr: VectorType"); - return {}; + + const mlir::Location loc = cgf.getLoc(e->getSourceRange()); + const mlir::Value vecValue = Visit(e->getBase()); + const mlir::Value indexValue = Visit(e->getIdx()); + return cgf.builder.create<cir::VecExtractOp>(loc, vecValue, indexValue); } // Just load the lvalue formed by the subscript expression. return emitLoadOfLValue(e); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6137adb1e9936..66f29f8f6cdd0 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1600,7 +1600,8 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMStackRestoreOpLowering, CIRToLLVMTrapOpLowering, CIRToLLVMUnaryOpLowering, - CIRToLLVMVecCreateOpLowering + CIRToLLVMVecCreateOpLowering, + CIRToLLVMVecExtractOpLowering // clang-format on >(converter, patterns.getContext()); @@ -1709,6 +1710,14 @@ mlir::LogicalResult CIRToLLVMVecCreateOpLowering::matchAndRewrite( return mlir::success(); } +mlir::LogicalResult CIRToLLVMVecExtractOpLowering::matchAndRewrite( + cir::VecExtractOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const { + rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractElementOp>( + op, adaptor.getVec(), adaptor.getIndex()); + return mlir::success(); +} + std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass() { return std::make_unique<ConvertCIRToLLVMPass>(); } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index f248ea31e7844..026505ea31b4c 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -303,6 +303,16 @@ class CIRToLLVMVecCreateOpLowering mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMVecExtractOpLowering + : public mlir::OpConversionPattern<cir::VecExtractOp> { +public: + using mlir::OpConversionPattern<cir::VecExtractOp>::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::VecExtractOp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + } // namespace direct } // namespace cir diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index a3880a944de1f..aeeaf655cad18 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -109,3 +109,36 @@ void foo2(vi4 p) {} // OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16 // OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16 + +void foo3() { + vi4 a = { 1, 2, 3, 4 }; + int e = a[1]; +} + +// CIR: %[[VEC:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i +// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i +// CIR: %[[VEC_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] : +// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: cir.store %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: %[[TMP:.*]] = cir.load %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> +// CIR: %[[IDX:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[ELE:.*]] = cir.vec.extract %[[TMP]][%[[IDX]] : !s32i] : !cir.vector<4 x !s32i> +// CIR: cir.store %[[ELE]], %[[INIT]] : !s32i, !cir.ptr<!s32i> + +// LLVM: %[[VEC:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// LLVM: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// LLVM: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 +// LLVM: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +// OGCG: %[[VEC:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// OGCG: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 +// OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index 76a85eab52380..9c85ed4a9e216 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -96,3 +96,36 @@ void foo2(vi4 p) {} // OGCG: %[[VEC_A:.*]] = alloca <4 x i32>, align 16 // OGCG: store <4 x i32> %{{.*}}, ptr %[[VEC_A]], align 16 + +void foo3() { + vi4 a = { 1, 2, 3, 4 }; + int e = a[1]; +} + +// CIR: %[[VEC:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i +// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i +// CIR: %[[VEC_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] : +// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: cir.store %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: %[[TMP:.*]] = cir.load %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> +// CIR: %[[IDX:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[ELE:.*]] = cir.vec.extract %[[TMP]][%[[IDX]] : !s32i] : !cir.vector<4 x !s32i> +// CIR: cir.store %[[ELE]], %[[INIT]] : !s32i, !cir.ptr<!s32i> + +// LLVM: %[[VEC:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// LLVM: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// LLVM: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 +// LLVM: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +// OGCG: %[[VEC:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// OGCG: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 +// OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 diff --git a/clang/test/CIR/IR/vector.cir b/clang/test/CIR/IR/vector.cir index d2612a7310ad0..aeb268e84c71c 100644 --- a/clang/test/CIR/IR/vector.cir +++ b/clang/test/CIR/IR/vector.cir @@ -65,4 +65,36 @@ cir.func @local_vector_create_test() { // CHECK: cir.return // CHECK: } +cir.func @vector_extract_element_test() { + %0 = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["d", init] + %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] + %2 = cir.const #cir.int<1> : !s32i + %3 = cir.const #cir.int<2> : !s32i + %4 = cir.const #cir.int<3> : !s32i + %5 = cir.const #cir.int<4> : !s32i + %6 = cir.vec.create(%2, %3, %4, %5 : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> + cir.store %6, %0 : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> + %7 = cir.load %0 : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> + %8 = cir.const #cir.int<1> : !s32i + %9 = cir.vec.extract %7[%8 : !s32i] : !cir.vector<4 x !s32i> + cir.store %9, %1 : !s32i, !cir.ptr<!s32i> + cir.return +} + +// CHECK: cir.func @vector_extract_element_test() { +// CHECK: %0 = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["d", init] +// CHECK: %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CHECK: %2 = cir.const #cir.int<1> : !s32i +// CHECK: %3 = cir.const #cir.int<2> : !s32i +// CHECK: %4 = cir.const #cir.int<3> : !s32i +// CHECK: %5 = cir.const #cir.int<4> : !s32i +// CHECK: %6 = cir.vec.create(%2, %3, %4, %5 : !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CHECK: cir.store %6, %0 : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CHECK: %7 = cir.load %0 : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> +// CHECK: %8 = cir.const #cir.int<1> : !s32i +// CHECK: %9 = cir.vec.extract %7[%8 : !s32i] : !cir.vector<4 x !s32i> +// CHECK: cir.store %9, %1 : !s32i, !cir.ptr<!s32i> +// CHECK: cir.return +// CHECK: } + } >From 80bd84c7ce48ed69c482805b65d1cbe3d7e5f693 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Sat, 3 May 2025 21:55:56 +0200 Subject: [PATCH 2/3] Address code review comment --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index b2121dee8d8b3..9d76f19a6a432 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1988,6 +1988,12 @@ def VecExtractOp : CIR_Op<"vec.extract", [Pure, let description = [{ The `cir.vec.extract` operation extracts the element at the given index from a vector object. + + ```mlir + %tmp = cir.load %vec : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> + %idx = cir.const #cir.int<1> : !s32i + %element = cir.vec.extract %tmp[%idx : !s32i] : !cir.vector<4 x !s32i> + ``` }]; let arguments = (ins CIR_VectorType:$vec, CIR_AnyFundamentalIntType:$index); @@ -1996,8 +2002,6 @@ def VecExtractOp : CIR_Op<"vec.extract", [Pure, let assemblyFormat = [{ $vec `[` $index `:` type($index) `]` attr-dict `:` qualified(type($vec)) }]; - - let hasVerifier = 0; } #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD >From e40d0dff9cce883bb7a6a79e4e76172da7618e33 Mon Sep 17 00:00:00 2001 From: AmrDeveloper <am...@programmer.net> Date: Wed, 7 May 2025 19:14:04 +0200 Subject: [PATCH 3/3] Add test cases for variable index --- clang/test/CIR/CodeGen/vector-ext.cpp | 44 +++++++++++++++++++++++++++ clang/test/CIR/CodeGen/vector.cpp | 44 +++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/clang/test/CIR/CodeGen/vector-ext.cpp b/clang/test/CIR/CodeGen/vector-ext.cpp index aeeaf655cad18..7f6a2057f9da4 100644 --- a/clang/test/CIR/CodeGen/vector-ext.cpp +++ b/clang/test/CIR/CodeGen/vector-ext.cpp @@ -142,3 +142,47 @@ void foo3() { // OGCG: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 // OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 // OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +void foo4() { + vi4 a = { 1, 2, 3, 4 }; + + int idx = 2; + int e = a[idx]; +} + +// CIR: %[[VEC:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init] +// CIR: %[[IDX:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["idx", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i +// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i +// CIR: %[[VEC_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] : +// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: cir.store %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: %[[CONST_IDX:.*]] = cir.const #cir.int<2> : !s32i +// CIR: cir.store %[[CONST_IDX]], %[[IDX]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[TMP1:.*]] = cir.load %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> +// CIR: %[[TMP2:.*]] = cir.load %[[IDX]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[ELE:.*]] = cir.vec.extract %[[TMP1]][%[[TMP2]] : !s32i] : !cir.vector<4 x !s32i> +// CIR: cir.store %[[ELE]], %[[INIT]] : !s32i, !cir.ptr<!s32i> + +// LLVM: %[[VEC:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[IDX:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// LLVM: store i32 2, ptr %[[IDX]], align 4 +// LLVM: %[[TMP1:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// LLVM: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 +// LLVM: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] +// LLVM: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +// OGCG: %[[VEC:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[IDX:.*]] = alloca i32, align 4 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// OGCG: store i32 2, ptr %[[IDX]], align 4 +// OGCG: %[[TMP1:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// OGCG: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 +// OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] +// OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 diff --git a/clang/test/CIR/CodeGen/vector.cpp b/clang/test/CIR/CodeGen/vector.cpp index 9c85ed4a9e216..36d68d9f42416 100644 --- a/clang/test/CIR/CodeGen/vector.cpp +++ b/clang/test/CIR/CodeGen/vector.cpp @@ -129,3 +129,47 @@ void foo3() { // OGCG: %[[TMP:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 // OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP]], i32 1 // OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +void foo4() { + vi4 a = { 1, 2, 3, 4 }; + + int idx = 2; + int e = a[idx]; +} + +// CIR: %[[VEC:.*]] = cir.alloca !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>>, ["a", init] +// CIR: %[[IDX:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["idx", init] +// CIR: %[[INIT:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["e", init] +// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i +// CIR: %[[CONST_2:.*]] = cir.const #cir.int<2> : !s32i +// CIR: %[[CONST_3:.*]] = cir.const #cir.int<3> : !s32i +// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !s32i +// CIR: %[[VEC_VAL:.*]] = cir.vec.create(%[[CONST_1]], %[[CONST_2]], %[[CONST_3]], %[[CONST_4]] : +// CIR-SAME: !s32i, !s32i, !s32i, !s32i) : !cir.vector<4 x !s32i> +// CIR: cir.store %[[VEC_VAL]], %[[VEC]] : !cir.vector<4 x !s32i>, !cir.ptr<!cir.vector<4 x !s32i>> +// CIR: %[[CONST_IDX:.*]] = cir.const #cir.int<2> : !s32i +// CIR: cir.store %[[CONST_IDX]], %[[IDX]] : !s32i, !cir.ptr<!s32i> +// CIR: %[[TMP1:.*]] = cir.load %[[VEC]] : !cir.ptr<!cir.vector<4 x !s32i>>, !cir.vector<4 x !s32i> +// CIR: %[[TMP2:.*]] = cir.load %[[IDX]] : !cir.ptr<!s32i>, !s32i +// CIR: %[[ELE:.*]] = cir.vec.extract %[[TMP1]][%[[TMP2]] : !s32i] : !cir.vector<4 x !s32i> +// CIR: cir.store %[[ELE]], %[[INIT]] : !s32i, !cir.ptr<!s32i> + +// LLVM: %[[VEC:.*]] = alloca <4 x i32>, i64 1, align 16 +// LLVM: %[[IDX:.*]] = alloca i32, i64 1, align 4 +// LLVM: %[[INIT:.*]] = alloca i32, i64 1, align 4 +// LLVM: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// LLVM: store i32 2, ptr %[[IDX]], align 4 +// LLVM: %[[TMP1:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// LLVM: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 +// LLVM: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] +// LLVM: store i32 %[[ELE]], ptr %[[INIT]], align 4 + +// OGCG: %[[VEC:.*]] = alloca <4 x i32>, align 16 +// OGCG: %[[IDX:.*]] = alloca i32, align 4 +// OGCG: %[[INIT:.*]] = alloca i32, align 4 +// OGCG: store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %[[VEC]], align 16 +// OGCG: store i32 2, ptr %[[IDX]], align 4 +// OGCG: %[[TMP1:.*]] = load <4 x i32>, ptr %[[VEC]], align 16 +// OGCG: %[[TMP2:.*]] = load i32, ptr %[[IDX]], align 4 +// OGCG: %[[ELE:.*]] = extractelement <4 x i32> %[[TMP1]], i32 %[[TMP2]] +// OGCG: store i32 %[[ELE]], ptr %[[INIT]], align 4 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits