r200114 - For AArch64 Neon, fix intrinsics implementation using nested macros.
Jiangning Liu
jiangning.liu at arm.com
Sat Jan 25 19:38:42 PST 2014
Author: jiangning
Date: Sat Jan 25 21:38:42 2014
New Revision: 200114
URL: http://llvm.org/viewvc/llvm-project?rev=200114&view=rev
Log:
For AArch64 Neon, fix intrinsics implementation using nested macros.
Modified:
cfe/trunk/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
cfe/trunk/utils/TableGen/NeonEmitter.cpp
Modified: cfe/trunk/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c?rev=200114&r1=200113&r2=200114&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c (original)
+++ cfe/trunk/test/CodeGen/aarch64-neon-scalar-x-indexed-elem.c Sat Jan 25 21:38:42 2014
@@ -253,3 +253,38 @@ int64_t test_vqdmlsls_laneq_s32(int64_t
// CHECK: sqdmlsl {{d[0-9]+}}, {{s[0-9]+}}, {{v[0-9]+}}.s[3]
}
+// CHECK-LABEL: test_vmulx_lane_f64_0:
+float64x1_t test_vmulx_lane_f64_0() {
+ float64x1_t arg1;
+ float64x1_t arg2;
+ float64x1_t result;
+ float64_t sarg1, sarg2, sres;
+ arg1 = vcreate_f64(UINT64_C(0x3fd6304bc43ab5c2));
+ arg2 = vcreate_f64(UINT64_C(0x3fee211e215aeef3));
+ result = vmulx_lane_f64(arg1, arg2, 0);
+// CHECK: adrp x0
+// CHECK: ldr d0, [x0,
+// CHECK: adrp x0
+// CHECK: ldr d1, [x0,
+// CHECK: fmulx d0, d1, d0
+ return result;
+}
+
+// CHECK-LABEL: test_vmulx_laneq_f64_2:
+float64x1_t test_vmulx_laneq_f64_2() {
+ float64x1_t arg1;
+ float64x1_t arg2;
+ float64x2_t arg3;
+ float64x1_t result;
+ float64_t sarg1, sarg2, sres;
+ arg1 = vcreate_f64(UINT64_C(0x3fd6304bc43ab5c2));
+ arg2 = vcreate_f64(UINT64_C(0x3fee211e215aeef3));
+ arg3 = vcombine_f64(arg1, arg2);
+ result = vmulx_laneq_f64(arg1, arg3, 1);
+// CHECK: adrp x0
+// CHECK: ldr d0, [x0,
+// CHECK: adrp x0
+// CHECK: ldr d1, [x0,
+// CHECK: fmulx d0, d1, d0
+ return result;
+}
Modified: cfe/trunk/utils/TableGen/NeonEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/NeonEmitter.cpp?rev=200114&r1=200113&r2=200114&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/NeonEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/NeonEmitter.cpp Sat Jan 25 21:38:42 2014
@@ -1483,9 +1483,6 @@ static std::string GenArgs(const std::st
s += TypeString(proto[i], typestr) + " __";
}
s.push_back(arg);
- //To avoid argument being multiple defined, add extra number for renaming.
- if (name == "vcopy_lane" || name == "vcopy_laneq")
- s.push_back('1');
if ((i + 1) < e)
s += ", ";
}
@@ -1508,18 +1505,10 @@ static std::string GenMacroLocals(const
if (MacroArgUsedDirectly(proto, i))
continue;
generatedLocal = true;
- bool extranumber = false;
- if (name == "vcopy_lane" || name == "vcopy_laneq")
- extranumber = true;
-
s += TypeString(proto[i], typestr) + " __";
s.push_back(arg);
- if(extranumber)
- s.push_back('1');
s += " = (";
s.push_back(arg);
- if(extranumber)
- s.push_back('1');
s += "); ";
}
@@ -1640,6 +1629,18 @@ static unsigned GetNumElements(StringRef
}
// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
+//
+// Note that some intrinsic definitions around 'lane' are being implemented
+// with macros, because they all contain constant integer argument, and we
+// statically check the range of the lane index to meet the semantic
+// requirement of different intrinsics.
+//
+// For the intrinsics implemented with macro, if they contain another intrinsic
+// implemented with maco, we have to avoid using the same argument names for
+// the nested instrinsics. For example, macro vfms_lane is being implemented
+// with another macor vfma_lane, so we rename all arguments for vfms_lane by
+// adding a suffix '1'.
+
static std::string GenOpString(const std::string &name, OpKind op,
const std::string &proto, StringRef typestr) {
bool quad;
@@ -2109,23 +2110,29 @@ static std::string GenOpString(const std
break;
}
case OpCopyLane: {
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n ";
s += TypeString('s', typestr) + " __c2 = " +
- MangleName("vget_lane", typestr, ClassS) + "(__c1, __d1); \\\n " +
- MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b1);";
+ MangleName("vget_lane", typestr, ClassS) + "(__c1, __d); \\\n " +
+ MangleName("vset_lane", typestr, ClassS) + "(__c2, __a1, __b);";
break;
}
case OpCopyQLane: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n ";
s += TypeString('s', typestr) + " __c2 = vget_lane_" + typeCode +
- "(__c1, __d1); \\\n vsetq_lane_" + typeCode + "(__c2, __a1, __b1);";
+ "(__c1, __d); \\\n vsetq_lane_" + typeCode + "(__c2, __a1, __b);";
break;
}
case OpCopyLaneQ: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[3], typestr) + " __c1 = __c; \\\n ";
s += TypeString('s', typestr) + " __c2 = vgetq_lane_" + typeCode +
- "(__c1, __d1); \\\n vset_lane_" + typeCode + "(__c2, __a1, __b1);";
+ "(__c1, __d); \\\n vset_lane_" + typeCode + "(__c2, __a1, __b);";
break;
}
case OpScalarMulLane: {
@@ -2138,8 +2145,10 @@ static std::string GenOpString(const std
case OpScalarMulLaneQ: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode +
- "(__b, __c);\\\n __a * __d1;";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += TypeString('s', typestr) + " __d1 = vgetq_lane_" + typeCode +
+ "(__b1, __c);\\\n __a1 * __d1;";
break;
}
case OpScalarMulXLane: {
@@ -2148,9 +2157,11 @@ static std::string GenOpString(const std
if (type == 'f') type = 's';
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
s += TypeString('s', typestr) + " __d1 = vget_lane_" + typeCode +
- "(__b, __c);\\\n vmulx" + type + "_" +
- typeCode + "(__a, __d1);";
+ "(__b1, __c);\\\n vmulx" + type + "_" +
+ typeCode + "(__a1, __d1);";
break;
}
case OpScalarMulXLaneQ: {
@@ -2159,9 +2170,11 @@ static std::string GenOpString(const std
if (type == 'f') type = 's';
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
s += TypeString('s', typestr) + " __d1 = vgetq_lane_" +
- typeCode + "(__b, __c);\\\n vmulx" + type +
- "_" + typeCode + "(__a, __d1);";
+ typeCode + "(__b1, __c);\\\n vmulx" + type +
+ "_" + typeCode + "(__a1, __d1);";
break;
}
@@ -2171,10 +2184,12 @@ static std::string GenOpString(const std
if (type == 'f') type = 's';
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
s += TypeString('s', typestr) + " __d1 = vget_lane_" +
- typeCode + "(__a, 0);\\\n" +
+ typeCode + "(__a1, 0);\\\n" +
" " + TypeString('s', typestr) + " __e1 = vget_lane_" +
- typeCode + "(__b, __c);\\\n" +
+ typeCode + "(__b1, __c);\\\n" +
" " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
typeCode + "(__d1, __e1);\\\n" +
" " + TypeString('d', typestr) + " __g1;\\\n" +
@@ -2188,10 +2203,12 @@ static std::string GenOpString(const std
if (type == 'f') type = 's';
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
s += TypeString('s', typestr) + " __d1 = vget_lane_" +
- typeCode + "(__a, 0);\\\n" +
+ typeCode + "(__a1, 0);\\\n" +
" " + TypeString('s', typestr) + " __e1 = vgetq_lane_" +
- typeCode + "(__b, __c);\\\n" +
+ typeCode + "(__b1, __c);\\\n" +
" " + TypeString('s', typestr) + " __f1 = vmulx" + type + "_" +
typeCode + "(__d1, __e1);\\\n" +
" " + TypeString('d', typestr) + " __g1;\\\n" +
@@ -2201,69 +2218,82 @@ static std::string GenOpString(const std
case OpScalarQDMullLane: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
- "vget_lane_" + typeCode + "(b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
+ "vget_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarQDMullLaneQ: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqdmull", typestr, ClassS) + "(__a, " +
- "vgetq_lane_" + typeCode + "(b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqdmull", typestr, ClassS) + "(__a1, " +
+ "vgetq_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarQDMulHiLane: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " +
- "vget_lane_" + typeCode + "(__b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
+ "vget_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarQDMulHiLaneQ: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqdmulh", typestr, ClassS) + "(__a, " +
- "vgetq_lane_" + typeCode + "(__b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqdmulh", typestr, ClassS) + "(__a1, " +
+ "vgetq_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarQRDMulHiLane: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " +
- "vget_lane_" + typeCode + "(__b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
+ "vget_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarQRDMulHiLaneQ: {
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += MangleName("vqrdmulh", typestr, ClassS) + "(__a, " +
- "vgetq_lane_" + typeCode + "(__b, __c));";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
+ s += TypeString(proto[2], typestr) + " __b1 = __b; \\\n ";
+ s += MangleName("vqrdmulh", typestr, ClassS) + "(__a1, " +
+ "vgetq_lane_" + typeCode + "(__b1, __c));";
break;
}
case OpScalarGetLane:{
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
if (quad) {
- s += "int16x8_t __a1 = vreinterpretq_s16_f16(__a);\\\n";
- s += " vgetq_lane_s16(__a1, __b);";
+ s += "int16x8_t __a2 = vreinterpretq_s16_f16(__a1);\\\n";
+ s += " vgetq_lane_s16(__a2, __b);";
} else {
- s += "int16x4_t __a1 = vreinterpret_s16_f16(__a);\\\n";
- s += " vget_lane_s16(__a1, __b);";
+ s += "int16x4_t __a2 = vreinterpret_s16_f16(__a1);\\\n";
+ s += " vget_lane_s16(__a2, __b);";
}
break;
}
case OpScalarSetLane:{
std::string typeCode = "";
InstructionTypeCode(typestr, ClassS, quad, typeCode);
- s += "int16_t __a1 = (int16_t)__a;\\\n";
+ s += TypeString(proto[1], typestr) + " __a1 = __a; \\\n ";
if (quad) {
- s += " int16x8_t __b1 = vreinterpretq_s16_f16(b);\\\n";
- s += " int16x8_t __b2 = vsetq_lane_s16(__a1, __b1, __c);\\\n";
- s += " vreinterpretq_f16_s16(__b2);";
+ s += " int16x8_t __b2 = vreinterpretq_s16_f16(b);\\\n";
+ s += " int16x8_t __b3 = vsetq_lane_s16(__a1, __b2, __c);\\\n";
+ s += " vreinterpretq_f16_s16(__b3);";
} else {
- s += " int16x4_t __b1 = vreinterpret_s16_f16(b);\\\n";
- s += " int16x4_t __b2 = vset_lane_s16(__a1, __b1, __c);\\\n";
- s += " vreinterpret_f16_s16(__b2);";
+ s += " int16x4_t __b2 = vreinterpret_s16_f16(b);\\\n";
+ s += " int16x4_t __b3 = vset_lane_s16(__a1, __b2, __c);\\\n";
+ s += " vreinterpret_f16_s16(__b3);";
}
break;
}
More information about the cfe-commits
mailing list