From bda9d2ebcb00e80d6b8ee340215c8d4ea7f35613 Mon Sep 17 00:00:00 2001 From: Hao Liu Date: Fri, 29 Nov 2013 02:13:17 +0000 Subject: [PATCH] Fix the problem that the range check for scalar narrow shift is too wide. E.g. the immediate value of vshrns_n_s16 is [1,16], which should be [1,8]. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195942 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/arm_neon.td | 19 ++++--- lib/CodeGen/CGBuiltin.cpp | 1 - test/CodeGen/aarch64-neon-intrinsics.c | 72 +++++++++++++------------- utils/TableGen/NeonEmitter.cpp | 8 ++- 4 files changed, 53 insertions(+), 47 deletions(-) diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 9158972954..a658f8e1c1 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -133,6 +133,7 @@ class Inst { Op Operand = o; bit isShift = 0; bit isScalarShift = 0; + bit isScalarNarrowShift = 0; bit isVCVT_N = 0; bit isA64 = 0; bit isCrypto = 0; @@ -1055,14 +1056,16 @@ def SCALAR_SRI_N: SInst<"vsri_n", "sssi", "SlSUl">; // Shift Left And Insert (Immediate) def SCALAR_SLI_N: SInst<"vsli_n", "sssi", "SlSUl">; -// Signed/Unsigned Saturating Shift Right Narrow (Immediate) -def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">; -// Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate) -def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">; -// Signed Saturating Shift Right Unsigned Narrow (Immediate) -def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">; -// Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) -def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">; +let isScalarNarrowShift = 1 in { + // Signed/Unsigned Saturating Shift Right Narrow (Immediate) + def SCALAR_SQSHRN_N: SInst<"vqshrn_n", "zsi", "SsSiSlSUsSUiSUl">; + // Signed/Unsigned Saturating Rounded Shift Right Narrow (Immediate) + def SCALAR_SQRSHRN_N: SInst<"vqrshrn_n", "zsi", "SsSiSlSUsSUiSUl">; + // Signed Saturating Shift Right Unsigned Narrow (Immediate) + def SCALAR_SQSHRUN_N: SInst<"vqshrun_n", "zsi", "SsSiSl">; + // Signed Saturating Rounded Shift Right Unsigned Narrow (Immediate) + def SCALAR_SQRSHRUN_N: SInst<"vqrshrun_n", "zsi", "SsSiSl">; +} //////////////////////////////////////////////////////////////////////////////// // Scalar Signed/Unsigned Fixed-point Convert To Floating-Point (Immediate) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index fa571d78cc..00e6bd14de 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -3669,7 +3669,6 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); } - return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqmovun_v, E); case AArch64::BI__builtin_neon_vrndn_v: case AArch64::BI__builtin_neon_vrndnq_v: { Int = Intrinsic::aarch64_neon_frintn; diff --git a/test/CodeGen/aarch64-neon-intrinsics.c b/test/CodeGen/aarch64-neon-intrinsics.c index a26bcf29c7..efa078b4bc 100644 --- a/test/CodeGen/aarch64-neon-intrinsics.c +++ b/test/CodeGen/aarch64-neon-intrinsics.c @@ -8869,110 +8869,110 @@ uint64x1_t test_vsli_n_u64(uint64x1_t a, uint64x1_t b) { int8_t test_vqshrnh_n_s16(int16_t a) { // CHECK-LABEL: test_vqshrnh_n_s16 -// CHECK: sqshrn {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (int8_t)vqshrnh_n_s16(a, 15); +// CHECK: sqshrn {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (int8_t)vqshrnh_n_s16(a, 8); } int16_t test_vqshrns_n_s32(int32_t a) { // CHECK-LABEL: test_vqshrns_n_s32 -// CHECK: sqshrn {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (int16_t)vqshrns_n_s32(a, 31); +// CHECK: sqshrn {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (int16_t)vqshrns_n_s32(a, 16); } int32_t test_vqshrnd_n_s64(int64_t a) { // CHECK-LABEL: test_vqshrnd_n_s64 -// CHECK: sqshrn {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (int32_t)vqshrnd_n_s64(a, 63); +// CHECK: sqshrn {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (int32_t)vqshrnd_n_s64(a, 32); } uint8_t test_vqshrnh_n_u16(uint16_t a) { // CHECK-LABEL: test_vqshrnh_n_u16 -// CHECK: uqshrn {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (uint8_t)vqshrnh_n_u16(a, 15); +// CHECK: uqshrn {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (uint8_t)vqshrnh_n_u16(a, 8); } uint16_t test_vqshrns_n_u32(uint32_t a) { // CHECK-LABEL: test_vqshrns_n_u32 -// CHECK: uqshrn {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (uint16_t)vqshrns_n_u32(a, 31); +// CHECK: uqshrn {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (uint16_t)vqshrns_n_u32(a, 16); } uint32_t test_vqshrnd_n_u64(uint64_t a) { // CHECK-LABEL: test_vqshrnd_n_u64 -// CHECK: uqshrn {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (uint32_t)vqshrnd_n_u64(a, 63); +// CHECK: uqshrn {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (uint32_t)vqshrnd_n_u64(a, 32); } int8_t test_vqrshrnh_n_s16(int16_t a) { // CHECK-LABEL: test_vqrshrnh_n_s16 -// CHECK: sqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (int8_t)vqrshrnh_n_s16(a, 15); +// CHECK: sqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (int8_t)vqrshrnh_n_s16(a, 8); } int16_t test_vqrshrns_n_s32(int32_t a) { // CHECK-LABEL: test_vqrshrns_n_s32 -// CHECK: sqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (int16_t)vqrshrns_n_s32(a, 31); +// CHECK: sqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (int16_t)vqrshrns_n_s32(a, 16); } int32_t test_vqrshrnd_n_s64(int64_t a) { // CHECK-LABEL: test_vqrshrnd_n_s64 -// CHECK: sqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (int32_t)vqrshrnd_n_s64(a, 63); +// CHECK: sqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (int32_t)vqrshrnd_n_s64(a, 32); } uint8_t test_vqrshrnh_n_u16(uint16_t a) { // CHECK-LABEL: test_vqrshrnh_n_u16 -// CHECK: uqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (uint8_t)vqrshrnh_n_u16(a, 15); +// CHECK: uqrshrn {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (uint8_t)vqrshrnh_n_u16(a, 8); } uint16_t test_vqrshrns_n_u32(uint32_t a) { // CHECK-LABEL: test_vqrshrns_n_u32 -// CHECK: uqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (uint16_t)vqrshrns_n_u32(a, 31); +// CHECK: uqrshrn {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (uint16_t)vqrshrns_n_u32(a, 16); } uint32_t test_vqrshrnd_n_u64(uint64_t a) { // CHECK-LABEL: test_vqrshrnd_n_u64 -// CHECK: uqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (uint32_t)vqrshrnd_n_u64(a, 63); +// CHECK: uqrshrn {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (uint32_t)vqrshrnd_n_u64(a, 32); } int8_t test_vqshrunh_n_s16(int16_t a) { // CHECK-LABEL: test_vqshrunh_n_s16 -// CHECK: sqshrun {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (int8_t)vqshrunh_n_s16(a, 15); +// CHECK: sqshrun {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (int8_t)vqshrunh_n_s16(a, 8); } int16_t test_vqshruns_n_s32(int32_t a) { // CHECK-LABEL: test_vqshruns_n_s32 -// CHECK: sqshrun {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (int16_t)vqshruns_n_s32(a, 31); +// CHECK: sqshrun {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (int16_t)vqshruns_n_s32(a, 16); } int32_t test_vqshrund_n_s64(int64_t a) { // CHECK-LABEL: test_vqshrund_n_s64 -// CHECK: sqshrun {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (int32_t)vqshrund_n_s64(a, 63); +// CHECK: sqshrun {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (int32_t)vqshrund_n_s64(a, 32); } int8_t test_vqrshrunh_n_s16(int16_t a) { // CHECK-LABEL: test_vqrshrunh_n_s16 -// CHECK: sqrshrun {{b[0-9]+}}, {{h[0-9]+}}, #15 - return (int8_t)vqrshrunh_n_s16(a, 15); +// CHECK: sqrshrun {{b[0-9]+}}, {{h[0-9]+}}, #8 + return (int8_t)vqrshrunh_n_s16(a, 8); } int16_t test_vqrshruns_n_s32(int32_t a) { // CHECK-LABEL: test_vqrshruns_n_s32 -// CHECK: sqrshrun {{h[0-9]+}}, {{s[0-9]+}}, #31 - return (int16_t)vqrshruns_n_s32(a, 31); +// CHECK: sqrshrun {{h[0-9]+}}, {{s[0-9]+}}, #16 + return (int16_t)vqrshruns_n_s32(a, 16); } int32_t test_vqrshrund_n_s64(int64_t a) { // CHECK-LABEL: test_vqrshrund_n_s64 -// CHECK: sqrshrun {{s[0-9]+}}, {{d[0-9]+}}, #63 - return (int32_t)vqrshrund_n_s64(a, 63); +// CHECK: sqrshrun {{s[0-9]+}}, {{d[0-9]+}}, #32 + return (int32_t)vqrshrund_n_s64(a, 32); } float32_t test_vcvts_n_f32_s32(int32_t a) { diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index aac2504f85..10b428d934 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -2827,8 +2827,12 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS, name.find("cvt") != std::string::npos) rangestr = "l = 1; "; - rangestr += "u = " + - utostr(RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti])); + unsigned upBound = RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti]); + // Narrow shift has half the upper bound + if (R->getValueAsBit("isScalarNarrowShift")) + upBound /= 2; + + rangestr += "u = " + utostr(upBound); } else if (R->getValueAsBit("isShift")) { // Builtins which are overloaded by type will need to have their upper // bound computed at Sema time based on the type constant. -- 2.40.0