[clang] d7fa903 - [CodeGen][X86] Emit fshl/fshr ir intrinsics for shiftleft128/shiftright128 ms intrinsics
Simon Pilgrim via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 15 02:23:01 PDT 2020
Author: Simon Pilgrim
Date: 2020-10-15T10:22:41+01:00
New Revision: d7fa9030d47fa62ad443717f4d1c8da4096a1d6c
URL: https://github.com/llvm/llvm-project/commit/d7fa9030d47fa62ad443717f4d1c8da4096a1d6c
DIFF: https://github.com/llvm/llvm-project/commit/d7fa9030d47fa62ad443717f4d1c8da4096a1d6c.diff
LOG: [CodeGen][X86] Emit fshl/fshr ir intrinsics for shiftleft128/shiftright128 ms intrinsics
Now that funnel shift handling is pretty good, we can use the intrinsics directly and avoid a lot of zext/trunc issues.
https://godbolt.org/z/YqhnnM
Differential Revision: https://reviews.llvm.org/D89405
Added:
Modified:
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/X86/ms-x86-intrinsics.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 45deb4164553..157dae2831f2 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -13926,25 +13926,15 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
}
case X86::BI__shiftleft128:
case X86::BI__shiftright128: {
- // FIXME: Once fshl/fshr no longer add an unneeded and and cmov, do this:
- // llvm::Function *F = CGM.getIntrinsic(
- // BuiltinID == X86::BI__shiftleft128 ? Intrinsic::fshl : Intrinsic::fshr,
- // Int64Ty);
- // Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
- // return Builder.CreateCall(F, Ops);
- llvm::Type *Int128Ty = Builder.getInt128Ty();
- Value *HighPart128 =
- Builder.CreateShl(Builder.CreateZExt(Ops[1], Int128Ty), 64);
- Value *LowPart128 = Builder.CreateZExt(Ops[0], Int128Ty);
- Value *Val = Builder.CreateOr(HighPart128, LowPart128);
- Value *Amt = Builder.CreateAnd(Builder.CreateZExt(Ops[2], Int128Ty),
- llvm::ConstantInt::get(Int128Ty, 0x3f));
- Value *Res;
- if (BuiltinID == X86::BI__shiftleft128)
- Res = Builder.CreateLShr(Builder.CreateShl(Val, Amt), 64);
- else
- Res = Builder.CreateLShr(Val, Amt);
- return Builder.CreateTrunc(Res, Int64Ty);
+ llvm::Function *F = CGM.getIntrinsic(
+ BuiltinID == X86::BI__shiftleft128 ? Intrinsic::fshl : Intrinsic::fshr,
+ Int64Ty);
+ // Flip low/high ops and zero-extend amount to matching type.
+ // shiftleft128(Low, High, Amt) -> fshl(High, Low, Amt)
+ // shiftright128(Low, High, Amt) -> fshr(High, Low, Amt)
+ std::swap(Ops[0], Ops[1]);
+ Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
+ return Builder.CreateCall(F, Ops);
}
case X86::BI_ReadWriteBarrier:
case X86::BI_ReadBarrier:
diff --git a/clang/test/CodeGen/X86/ms-x86-intrinsics.c b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
index ffcf09052bab..6f745ff00f54 100644
--- a/clang/test/CodeGen/X86/ms-x86-intrinsics.c
+++ b/clang/test/CodeGen/X86/ms-x86-intrinsics.c
@@ -144,14 +144,8 @@ unsigned __int64 test__shiftleft128(unsigned __int64 l, unsigned __int64 h,
return __shiftleft128(l, h, d);
}
// CHECK-X64-LABEL: define dso_local i64 @test__shiftleft128(i64 %l, i64 %h, i8 %d)
-// CHECK-X64: = zext i64 %{{.*}} to i128
-// CHECK-X64: = shl nuw i128 %{{.*}}, 64
-// CHECK-X64: = zext i64 %{{.*}} to i128
-// CHECK-X64: = or i128 %
-// CHECK-X64: = and i8 %{{.*}}, 63
-// CHECK-X64: = shl i128 %
-// CHECK-X64: = lshr i128 %
-// CHECK-X64: = trunc i128 %
+// CHECK-X64: = zext i8 %{{.*}} to i64
+// CHECK-X64: = tail call i64 @llvm.fshl.i64(i64 %h, i64 %l, i64 %{{.*}})
// CHECK-X64: ret i64 %
unsigned __int64 test__shiftright128(unsigned __int64 l, unsigned __int64 h,
@@ -159,13 +153,8 @@ unsigned __int64 test__shiftright128(unsigned __int64 l, unsigned __int64 h,
return __shiftright128(l, h, d);
}
// CHECK-X64-LABEL: define dso_local i64 @test__shiftright128(i64 %l, i64 %h, i8 %d)
-// CHECK-X64: = zext i64 %{{.*}} to i128
-// CHECK-X64: = shl nuw i128 %{{.*}}, 64
-// CHECK-X64: = zext i64 %{{.*}} to i128
-// CHECK-X64: = or i128 %
-// CHECK-X64: = and i8 %{{.*}}, 63
-// CHECK-X64: = lshr i128 %
-// CHECK-X64: = trunc i128 %
+// CHECK-X64: = zext i8 %{{.*}} to i64
+// CHECK-X64: = tail call i64 @llvm.fshr.i64(i64 %h, i64 %l, i64 %{{.*}})
// CHECK-X64: ret i64 %
#endif // defined(__x86_64__)
More information about the cfe-commits
mailing list