Author: Craig Topper Date: 2022-06-26T13:51:17-07:00 New Revision: 016342e319fd31e41cf5ed16a6140a8ea2de74dd
URL: https://github.com/llvm/llvm-project/commit/016342e319fd31e41cf5ed16a6140a8ea2de74dd DIFF: https://github.com/llvm/llvm-project/commit/016342e319fd31e41cf5ed16a6140a8ea2de74dd.diff LOG: [RISCV] Evaluate ICE operands to builtins using getIntegerConstantExpr. Some RISC-V builtins requires ICE operands. We should call getIntegerConstantExpr instead of EmitScalarExpr to match other targets. This was made a little trickier by the vector intrinsics not having a valid type string, but there are two that have ICE operands so I specified them manually. Added: clang/test/CodeGen/RISCV/rvv-intrinsics/vget-vset-ice.cpp Modified: clang/lib/CodeGen/CGBuiltin.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 019fe4e7f0fb4..b22d1f76c1a1d 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19009,8 +19009,34 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, SmallVector<Value *, 4> Ops; llvm::Type *ResultType = ConvertType(E->getType()); - for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) - Ops.push_back(EmitScalarExpr(E->getArg(i))); + // Find out if any arguments are required to be integer constant expressions. + unsigned ICEArguments = 0; + ASTContext::GetBuiltinTypeError Error; + getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); + if (Error == ASTContext::GE_Missing_type) { + // Vector intrinsics don't have a type string. + assert(BuiltinID >= clang::RISCV::FirstRVVBuiltin && + BuiltinID <= clang::RISCV::LastRVVBuiltin); + ICEArguments = 0; + if (BuiltinID == RISCVVector::BI__builtin_rvv_vget_v || + BuiltinID == RISCVVector::BI__builtin_rvv_vset_v) + ICEArguments = 1 << 1; + } else { + assert(Error == ASTContext::GE_None && "Unexpected error"); + } + + for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { + // If this is a normal argument, just emit it as a scalar. + if ((ICEArguments & (1 << i)) == 0) { + Ops.push_back(EmitScalarExpr(E->getArg(i))); + continue; + } + + // If this is required to be a constant, constant fold it so that we know + // that the generated intrinsic gets a ConstantInt. + Ops.push_back(llvm::ConstantInt::get( + getLLVMContext(), *E->getArg(i)->getIntegerConstantExpr(getContext()))); + } Intrinsic::ID ID = Intrinsic::not_intrinsic; unsigned NF = 1; diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics/vget-vset-ice.cpp b/clang/test/CodeGen/RISCV/rvv-intrinsics/vget-vset-ice.cpp new file mode 100644 index 0000000000000..bb43b4018ee2d --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics/vget-vset-ice.cpp @@ -0,0 +1,29 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +f -target-feature +d \ +// RUN: -target-feature +v -target-feature +zfh -target-feature +experimental-zvfh \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -mem2reg | FileCheck --check-prefix=CHECK-RV64 %s + +#include <riscv_vector.h> + +// Use constexpr function to make sure we correctly evaluate it as a constant +// when emitting IR for the vget/vset builtins. +constexpr int foo() { return 1; } + +// CHECK-RV64-LABEL: @_Z21test_vget_v_i8m2_i8m1u14__rvv_int8m2_t +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.experimental.vector.extract.nxv8i8.nxv16i8(<vscale x 16 x i8> [[SRC:%.*]], i64 8) +// CHECK-RV64-NEXT: ret <vscale x 8 x i8> [[TMP0]] +// +vint8m1_t test_vget_v_i8m2_i8m1(vint8m2_t src) { + return vget_v_i8m2_i8m1(src, foo()); +} + +// CHECK-RV64-LABEL: @_Z21test_vset_v_i8m1_i8m2u14__rvv_int8m2_tu14__rvv_int8m1_t +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.experimental.vector.insert.nxv16i8.nxv8i8(<vscale x 16 x i8> [[DEST:%.*]], <vscale x 8 x i8> [[VAL:%.*]], i64 8) +// CHECK-RV64-NEXT: ret <vscale x 16 x i8> [[TMP0]] +// +vint8m2_t test_vset_v_i8m1_i8m2(vint8m2_t dest, vint8m1_t val) { + return vset_v_i8m1_i8m2(dest, foo(), val); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits