summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/arm_neon.td12
-rw-r--r--clang/lib/Sema/SemaChecking.cpp4
-rw-r--r--clang/utils/TableGen/NeonEmitter.cpp8
3 files changed, 20 insertions, 4 deletions
diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td
index a1065d9f720..02d67084f7a 100644
--- a/clang/include/clang/Basic/arm_neon.td
+++ b/clang/include/clang/Basic/arm_neon.td
@@ -148,6 +148,10 @@ class Inst <string n, string p, string t, Op o> {
bit isVCVT_N = 0;
bit isA64 = 0;
bit isCrypto = 0;
+ // For immediate checks: the immediate will be assumed to specify the lane of
+ // a Q register. Only used for intrinsics which end up calling polymorphic
+ // builtins.
+ bit isLaneQ = 0;
// Certain intrinsics have different names than their representative
// instructions. This field allows us to handle this correctly when we
@@ -909,7 +913,9 @@ def VMLS_LANEQ : IOpInst<"vmls_laneq", "dddji",
"siUsUifQsQiQUsQUiQf", OP_MLS_LN>;
def VFMA_LANE : IInst<"vfma_lane", "dddgi", "fdQfQd">;
-def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd">;
+def VFMA_LANEQ : IInst<"vfma_laneq", "dddji", "fdQfQd"> {
+ let isLaneQ = 1;
+}
def VFMS_LANE : IOpInst<"vfms_lane", "dddgi", "fdQfQd", OP_FMS_LN>;
def VFMS_LANEQ : IOpInst<"vfms_laneq", "dddji", "fdQfQd", OP_FMS_LNQ>;
@@ -1302,7 +1308,9 @@ def SCALAR_VMUL_N : IInst<"vmul_n", "dds", "d">;
def SCALAR_VMUL_LANE : IInst<"vmul_lane", "ddgi", "d">;
// VMUL_LANEQ d type implemented using scalar mul lane
-def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d">;
+def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "ddji", "d"> {
+ let isLaneQ = 1;
+}
// VMULX_LANE d type implemented using scalar vmulx_lane
def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "d", OP_SCALAR_VMULX_LN>;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 07f25c15faa..dfacba84efe 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -326,9 +326,9 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
}
// Get the valid immediate range for the specified NEON type code.
-static unsigned RFT(unsigned t, bool shift = false) {
+static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) {
NeonTypeFlags Type(t);
- int IsQuad = Type.isQuad();
+ int IsQuad = ForceQuad ? true : Type.isQuad();
switch (Type.getEltType()) {
case NeonTypeFlags::Int8:
case NeonTypeFlags::Poly8:
diff --git a/clang/utils/TableGen/NeonEmitter.cpp b/clang/utils/TableGen/NeonEmitter.cpp
index ac9e22491e6..e4c6cb3b1d7 100644
--- a/clang/utils/TableGen/NeonEmitter.cpp
+++ b/clang/utils/TableGen/NeonEmitter.cpp
@@ -3007,6 +3007,14 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
rangestr = "l = 1; ";
rangestr += "u = RFT(TV" + shiftstr + ")";
+ } else if (ck == ClassB) {
+ // ClassB intrinsics have a type (and hence lane number) that is only
+ // known at runtime.
+ assert(immPos > 0 && "unexpected immediate operand");
+ if (R->getValueAsBit("isLaneQ"))
+ rangestr = "u = RFT(TV, false, true)";
+ else
+ rangestr = "u = RFT(TV, false, false)";
} else {
// The immediate generally refers to a lane in the preceding argument.
assert(immPos > 0 && "unexpected immediate operand");
OpenPOWER on IntegriCloud