mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
Legalizer: Use the scalar bit width when promoting bit counting instrs on
vectors. e.g. when promoting ctlz from <2 x i32> to <2 x i64> we have to fixup the result by 32 bits, not 64. PR20917. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217671 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -342,9 +342,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
|
|||||||
EVT NVT = Op.getValueType();
|
EVT NVT = Op.getValueType();
|
||||||
Op = DAG.getNode(N->getOpcode(), dl, NVT, Op);
|
Op = DAG.getNode(N->getOpcode(), dl, NVT, Op);
|
||||||
// Subtract off the extra leading bits in the bigger type.
|
// Subtract off the extra leading bits in the bigger type.
|
||||||
return DAG.getNode(ISD::SUB, dl, NVT, Op,
|
return DAG.getNode(
|
||||||
DAG.getConstant(NVT.getSizeInBits() -
|
ISD::SUB, dl, NVT, Op,
|
||||||
OVT.getSizeInBits(), NVT));
|
DAG.getConstant(NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits(),
|
||||||
|
NVT));
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
|
SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
|
||||||
@@ -362,8 +363,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
|
|||||||
// The count is the same in the promoted type except if the original
|
// The count is the same in the promoted type except if the original
|
||||||
// value was zero. This can be handled by setting the bit just off
|
// value was zero. This can be handled by setting the bit just off
|
||||||
// the top of the original type.
|
// the top of the original type.
|
||||||
APInt TopBit(NVT.getSizeInBits(), 0);
|
auto TopBit = APInt::getOneBitSet(NVT.getScalarSizeInBits(),
|
||||||
TopBit.setBit(OVT.getSizeInBits());
|
OVT.getScalarSizeInBits());
|
||||||
Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
|
Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
|
||||||
}
|
}
|
||||||
return DAG.getNode(N->getOpcode(), dl, NVT, Op);
|
return DAG.getNode(N->getOpcode(), dl, NVT, Op);
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -march=x86-64
|
; RUN: llc < %s -march=x86-64 -mattr=+sse2 | FileCheck %s
|
||||||
|
|
||||||
declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1)
|
declare <2 x i64> @llvm.cttz.v2i64(<2 x i64>, i1)
|
||||||
declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1)
|
declare <2 x i64> @llvm.ctlz.v2i64(<2 x i64>, i1)
|
||||||
@@ -7,12 +7,61 @@ declare <2 x i64> @llvm.ctpop.v2i64(<2 x i64>)
|
|||||||
define <2 x i64> @footz(<2 x i64> %a) nounwind {
|
define <2 x i64> @footz(<2 x i64> %a) nounwind {
|
||||||
%c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true)
|
%c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true)
|
||||||
ret <2 x i64> %c
|
ret <2 x i64> %c
|
||||||
|
|
||||||
|
; CHECK-LABEL: footz
|
||||||
|
; CHECK: bsfq
|
||||||
|
; CHECK: bsfq
|
||||||
}
|
}
|
||||||
define <2 x i64> @foolz(<2 x i64> %a) nounwind {
|
define <2 x i64> @foolz(<2 x i64> %a) nounwind {
|
||||||
%c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 true)
|
%c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 true)
|
||||||
ret <2 x i64> %c
|
ret <2 x i64> %c
|
||||||
|
|
||||||
|
; CHECK-LABEL: foolz
|
||||||
|
; CHECK: bsrq
|
||||||
|
; CHECK: xorq $63
|
||||||
|
; CHECK: bsrq
|
||||||
|
; CHECK: xorq $63
|
||||||
}
|
}
|
||||||
|
|
||||||
define <2 x i64> @foopop(<2 x i64> %a) nounwind {
|
define <2 x i64> @foopop(<2 x i64> %a) nounwind {
|
||||||
%c = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
|
%c = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
|
||||||
ret <2 x i64> %c
|
ret <2 x i64> %c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1)
|
||||||
|
declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1)
|
||||||
|
declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)
|
||||||
|
|
||||||
|
define <2 x i32> @promtz(<2 x i32> %a) nounwind {
|
||||||
|
%c = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %a, i1 false)
|
||||||
|
ret <2 x i32> %c
|
||||||
|
|
||||||
|
; CHECK: .quad 4294967296
|
||||||
|
; CHECK: .quad 4294967296
|
||||||
|
; CHECK-LABEL: promtz
|
||||||
|
; CHECK: bsfq
|
||||||
|
; CHECK: cmov
|
||||||
|
; CHECK: bsfq
|
||||||
|
; CHECK: cmov
|
||||||
|
}
|
||||||
|
define <2 x i32> @promlz(<2 x i32> %a) nounwind {
|
||||||
|
%c = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %a, i1 false)
|
||||||
|
ret <2 x i32> %c
|
||||||
|
|
||||||
|
; CHECK: .quad 4294967295
|
||||||
|
; CHECK: .quad 4294967295
|
||||||
|
; CHECK: .quad 32
|
||||||
|
; CHECK: .quad 32
|
||||||
|
; CHECK-LABEL: promlz
|
||||||
|
; CHECK: pand
|
||||||
|
; CHECK: bsrq
|
||||||
|
; CHECK: xorq $63
|
||||||
|
; CHECK: bsrq
|
||||||
|
; CHECK: xorq $63
|
||||||
|
; CHECK: psub
|
||||||
|
}
|
||||||
|
|
||||||
|
define <2 x i32> @prompop(<2 x i32> %a) nounwind {
|
||||||
|
%c = call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a)
|
||||||
|
ret <2 x i32> %c
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user