mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-22 08:32:23 +00:00
[OpenCL] Add ExtVectorElementExpr constant evaluation (PR42387)
Add constexpr evaluation for ExtVectorElementExpr nodes by evaluating the underlying vector expression. Add basic folding for the case that Evaluate does not return an LValue. Differential Revision: https://reviews.llvm.org/D71133
This commit is contained in:
parent
870f39d310
commit
df5a905aa8
@ -7080,6 +7080,31 @@ public:
|
||||
DerivedSuccess(Result, E);
|
||||
}
|
||||
|
||||
bool VisitExtVectorElementExpr(const ExtVectorElementExpr *E) {
|
||||
APValue Val;
|
||||
if (!Evaluate(Val, Info, E->getBase()))
|
||||
return false;
|
||||
|
||||
if (Val.isVector()) {
|
||||
SmallVector<uint32_t, 4> Indices;
|
||||
E->getEncodedElementAccess(Indices);
|
||||
if (Indices.size() == 1) {
|
||||
// Return scalar.
|
||||
return DerivedSuccess(Val.getVectorElt(Indices[0]), E);
|
||||
} else {
|
||||
// Construct new APValue vector.
|
||||
SmallVector<APValue, 4> Elts;
|
||||
for (unsigned I = 0; I < Indices.size(); ++I) {
|
||||
Elts.push_back(Val.getVectorElt(Indices[I]));
|
||||
}
|
||||
APValue VecResult(Elts.data(), Indices.size());
|
||||
return DerivedSuccess(VecResult, E);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VisitCastExpr(const CastExpr *E) {
|
||||
switch (E->getCastKind()) {
|
||||
default:
|
||||
|
@ -1,5 +1,8 @@
|
||||
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=clc++ -O0 -emit-llvm -o - | FileCheck %s
|
||||
|
||||
typedef int int2 __attribute__((ext_vector_type(2)));
|
||||
typedef int int4 __attribute__((ext_vector_type(4)));
|
||||
|
||||
struct Storage final {
|
||||
constexpr const float& operator[](const int index) const noexcept {
|
||||
return InternalStorage[index];
|
||||
@ -24,3 +27,28 @@ constexpr float FloatConstant = compute();
|
||||
kernel void foo(global float *x) {
|
||||
*x = FloatConstant;
|
||||
}
|
||||
|
||||
// Test evaluation of constant vectors.
|
||||
// CHECK-LABEL: define spir_kernel void @vecEval
|
||||
// CHECK: store i32 3
|
||||
// CHECK: store <2 x i32> <i32 22, i32 33>, <2 x i32>
|
||||
|
||||
const int oneElt = int4(3).x;
|
||||
const int2 twoElts = (int4)(11, 22, 33, 44).yz;
|
||||
|
||||
kernel void vecEval(global int *x, global int2 *y) {
|
||||
*x = oneElt;
|
||||
*y = twoElts;
|
||||
}
|
||||
|
||||
// Test evaluation of vectors initialized through a constexpr function.
|
||||
// CHECK-LABEL: define spir_kernel void @vecEval2
|
||||
// CHECK: store <2 x i32>
|
||||
constexpr int2 addOne(int2 x) {
|
||||
return (int2)(x.x + 1, x.y + 1);
|
||||
}
|
||||
const int2 fromConstexprFunc = addOne(int2(2));
|
||||
|
||||
kernel void vecEval2(global int2 *x) {
|
||||
*x = fromConstexprFunc;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user