mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[SelectionDAG] try to convert funnel shift directly to rotate if legal
If the DAGCombiner's rotate matching was working as expected, I don't think we'd see any test diffs here. This sidesteps the issue of custom lowering for rotates raised in PR38243: https://bugs.llvm.org/show_bug.cgi?id=38243 ...by only dealing with legal operations. llvm-svn: 337966
This commit is contained in:
parent
cc01a9a147
commit
a9aafee89e
@ -377,6 +377,8 @@ namespace ISD {
|
||||
/// When the 1st operand is a vector, the shift amount must be in the same
|
||||
/// type. (TLI.getShiftAmountTy() will return the same type when the input
|
||||
/// type is a vector.)
|
||||
/// For rotates, the shift amount is treated as an unsigned amount modulo
|
||||
/// the element size of the first operand.
|
||||
SHL, SRA, SRL, ROTL, ROTR,
|
||||
|
||||
/// Byte Swap and Counting operators.
|
||||
|
@ -5672,7 +5672,16 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
SDValue Z = getValue(I.getArgOperand(2));
|
||||
EVT VT = X.getValueType();
|
||||
|
||||
// TODO: When X == Y, this is rotate. Create the node directly if legal.
|
||||
// When X == Y, this is rotate. Create the node directly if legal.
|
||||
// TODO: This should also be done if the operation is custom, but we have
|
||||
// to make sure targets are handling the modulo shift amount as expected.
|
||||
// TODO: If the rotate direction (left or right) corresponding to the shift
|
||||
// is not available, adjust the shift value and invert the direction.
|
||||
auto RotateOpcode = IsFSHL ? ISD::ROTL : ISD::ROTR;
|
||||
if (X == Y && TLI.isOperationLegal(RotateOpcode, VT)) {
|
||||
setValue(&I, DAG.getNode(RotateOpcode, sdl, VT, X, Z));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the shift amount and inverse shift amount, modulo the bit-width.
|
||||
SDValue BitWidthC = DAG.getConstant(VT.getScalarSizeInBits(), sdl, VT);
|
||||
|
@ -163,11 +163,7 @@ define i32 @rotr_i32(i32 %x, i32 %z) {
|
||||
define i64 @rotr_i64(i64 %x, i64 %z) {
|
||||
; CHECK-LABEL: rotr_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: orr w9, wzr, #0x40
|
||||
; CHECK-NEXT: sub w9, w9, w1
|
||||
; CHECK-NEXT: lsr x8, x0, x1
|
||||
; CHECK-NEXT: lsl x9, x0, x9
|
||||
; CHECK-NEXT: orr x0, x9, x8
|
||||
; CHECK-NEXT: ror x0, x0, x1
|
||||
; CHECK-NEXT: ret
|
||||
%f = call i64 @llvm.fshr.i64(i64 %x, i64 %x, i64 %z)
|
||||
ret i64 %f
|
||||
|
@ -55,7 +55,6 @@ define i16 @rotl_i16(i16 %x, i16 %z) {
|
||||
define i32 @rotl_i32(i32 %x, i32 %z) {
|
||||
; CHECK-LABEL: rotl_i32:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: rlwinm 4, 4, 0, 27, 31
|
||||
; CHECK-NEXT: rlwnm 3, 3, 4, 0, 31
|
||||
; CHECK-NEXT: blr
|
||||
%f = call i32 @llvm.fshl.i32(i32 %x, i32 %x, i32 %z)
|
||||
@ -65,8 +64,7 @@ define i32 @rotl_i32(i32 %x, i32 %z) {
|
||||
define i64 @rotl_i64(i64 %x, i64 %z) {
|
||||
; CHECK-LABEL: rotl_i64:
|
||||
; CHECK: # %bb.0:
|
||||
; CHECK-NEXT: rlwinm 4, 4, 0, 26, 31
|
||||
; CHECK-NEXT: rotld 3, 3, 4
|
||||
; CHECK-NEXT: rldcl 3, 3, 4, 0
|
||||
; CHECK-NEXT: blr
|
||||
%f = call i64 @llvm.fshl.i64(i64 %x, i64 %x, i64 %z)
|
||||
ret i64 %f
|
||||
|
@ -169,12 +169,12 @@ define i8 @rotr_i8_const_shift(i8 %x) nounwind {
|
||||
; X32-SSE2-LABEL: rotr_i8_const_shift:
|
||||
; X32-SSE2: # %bb.0:
|
||||
; X32-SSE2-NEXT: movb {{[0-9]+}}(%esp), %al
|
||||
; X32-SSE2-NEXT: rolb $5, %al
|
||||
; X32-SSE2-NEXT: rorb $3, %al
|
||||
; X32-SSE2-NEXT: retl
|
||||
;
|
||||
; X64-AVX2-LABEL: rotr_i8_const_shift:
|
||||
; X64-AVX2: # %bb.0:
|
||||
; X64-AVX2-NEXT: rolb $5, %dil
|
||||
; X64-AVX2-NEXT: rorb $3, %dil
|
||||
; X64-AVX2-NEXT: movl %edi, %eax
|
||||
; X64-AVX2-NEXT: retq
|
||||
%f = call i8 @llvm.fshr.i8(i8 %x, i8 %x, i8 3)
|
||||
@ -185,12 +185,12 @@ define i32 @rotr_i32_const_shift(i32 %x) nounwind {
|
||||
; X32-SSE2-LABEL: rotr_i32_const_shift:
|
||||
; X32-SSE2: # %bb.0:
|
||||
; X32-SSE2-NEXT: movl {{[0-9]+}}(%esp), %eax
|
||||
; X32-SSE2-NEXT: roll $29, %eax
|
||||
; X32-SSE2-NEXT: rorl $3, %eax
|
||||
; X32-SSE2-NEXT: retl
|
||||
;
|
||||
; X64-AVX2-LABEL: rotr_i32_const_shift:
|
||||
; X64-AVX2: # %bb.0:
|
||||
; X64-AVX2-NEXT: roll $29, %edi
|
||||
; X64-AVX2-NEXT: rorl $3, %edi
|
||||
; X64-AVX2-NEXT: movl %edi, %eax
|
||||
; X64-AVX2-NEXT: retq
|
||||
%f = call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 3)
|
||||
|
Loading…
Reference in New Issue
Block a user