r208761 - [ARM64]Fix the bug right shift uint64_t by 64 generates incorrect result.
Hao Liu
Hao.Liu at arm.com
Wed May 14 01:59:31 PDT 2014
Author: haoliu
Date: Wed May 14 03:59:30 2014
New Revision: 208761
URL: http://llvm.org/viewvc/llvm-project?rev=208761&view=rev
Log:
[ARM64]Fix the bug right shift uint64_t by 64 generates incorrect result.
Modified:
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/test/CodeGen/aarch64-neon-intrinsics.c
Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=208761&r1=208760&r2=208761&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Wed May 14 03:59:30 2014
@@ -5580,38 +5580,41 @@ Value *CodeGenFunction::EmitARM64Builtin
case NEON::BI__builtin_neon_vshld_n_u64: {
llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
return Builder.CreateShl(
- Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
- Amt->getZExtValue())),
- "vshr_n");
+ Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
}
case NEON::BI__builtin_neon_vshrd_n_s64: {
llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
return Builder.CreateAShr(
Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
Amt->getZExtValue())),
- "vshr_n");
+ "shrd_n");
}
case NEON::BI__builtin_neon_vshrd_n_u64: {
llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
- return Builder.CreateLShr(
- Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
- Amt->getZExtValue())),
- "vshr_n");
+ uint64_t ShiftAmt = Amt->getZExtValue();
+ // Right-shifting an unsigned value by its size yields 0.
+ if (ShiftAmt == 64)
+ return ConstantInt::get(Int64Ty, 0);
+ return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
+ "shrd_n");
}
case NEON::BI__builtin_neon_vsrad_n_s64: {
llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
Ops[1] = Builder.CreateAShr(
Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
Amt->getZExtValue())),
- "vshr_n");
+ "shrd_n");
return Builder.CreateAdd(Ops[0], Ops[1]);
}
case NEON::BI__builtin_neon_vsrad_n_u64: {
llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
- Ops[1] = Builder.CreateLShr(
- Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
- Amt->getZExtValue())),
- "vshr_n");
+ uint64_t ShiftAmt = Amt->getZExtValue();
+ // Right-shifting an unsigned value by its size yields 0.
+ // As Op + 0 = Op, return Ops[0] directly.
+ if (ShiftAmt == 64)
+ return Ops[0];
+ Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
+ "shrd_n");
return Builder.CreateAdd(Ops[0], Ops[1]);
}
case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
Modified: cfe/trunk/test/CodeGen/aarch64-neon-intrinsics.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/aarch64-neon-intrinsics.c?rev=208761&r1=208760&r2=208761&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/aarch64-neon-intrinsics.c (original)
+++ cfe/trunk/test/CodeGen/aarch64-neon-intrinsics.c Wed May 14 03:59:30 2014
@@ -8572,11 +8572,24 @@ int64x1_t test_vshr_n_s64(int64x1_t a) {
}
uint64_t test_vshrd_n_u64(uint64_t a) {
-// CHECK-LABEL: test_vshrd_n_u64
-// CHECK: {{ushr d[0-9]+, d[0-9]+, #64|lsr x0, x0, #63}}
+// CHECK-AARCH64-LABEL: test_vshrd_n_u64
+// CHECK-AARCH64: {{ushr d[0-9]+, d[0-9]+, #64}}
+
+// CHECK-ARM64-LABEL: test_vshrd_n_u64
+// CHECK-ARM64: mov x0, xzr
return (uint64_t)vshrd_n_u64(a, 64);
}
+uint64_t test_vshrd_n_u64_2() {
+// CHECK-AARCH64-LABEL: test_vshrd_n_u64_2
+// CHECK-AARCH64: {{ushr d[0-9]+, d[0-9]+, #64}}
+
+// CHECK-ARM64-LABEL: test_vshrd_n_u64_2
+// CHECK-ARM64: mov x0, xzr
+ uint64_t a = UINT64_C(0xf000000000000000);
+ return vshrd_n_u64(a, 64);
+}
+
uint64x1_t test_vshr_n_u64(uint64x1_t a) {
// CHECK-LABEL: test_vshr_n_u64
// CHECK: ushr {{d[0-9]+}}, {{d[0-9]+}}, #1
@@ -8625,6 +8638,15 @@ uint64_t test_vsrad_n_u64(uint64_t a, ui
return (uint64_t)vsrad_n_u64(a, b, 63);
}
+uint64_t test_vsrad_n_u64_2(uint64_t a, uint64_t b) {
+// CHECK-AARCH64-LABEL: test_vsrad_n_u64_2
+// CHECK-AARCH64: {{usra d[0-9]+, d[0-9]+, #64}}
+
+// CHECK-ARM64-LABEL: test_vsrad_n_u64_2
+// CHECK-ARM64-NOT: add
+ return (uint64_t)vsrad_n_u64(a, b, 64);
+}
+
uint64x1_t test_vsra_n_u64(uint64x1_t a, uint64x1_t b) {
// CHECK-LABEL: test_vsra_n_u64
// CHECK: usra d{{[0-9]+}}, d{{[0-9]+}}, #1
More information about the cfe-commits
mailing list