mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +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:
parent
4a93e8dd02
commit
66feb63c3c
@ -342,9 +342,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
|
||||
EVT NVT = Op.getValueType();
|
||||
Op = DAG.getNode(N->getOpcode(), dl, NVT, Op);
|
||||
// Subtract off the extra leading bits in the bigger type.
|
||||
return DAG.getNode(ISD::SUB, dl, NVT, Op,
|
||||
DAG.getConstant(NVT.getSizeInBits() -
|
||||
OVT.getSizeInBits(), NVT));
|
||||
return DAG.getNode(
|
||||
ISD::SUB, dl, NVT, Op,
|
||||
DAG.getConstant(NVT.getScalarSizeInBits() - OVT.getScalarSizeInBits(),
|
||||
NVT));
|
||||
}
|
||||
|
||||
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
|
||||
// value was zero. This can be handled by setting the bit just off
|
||||
// the top of the original type.
|
||||
APInt TopBit(NVT.getSizeInBits(), 0);
|
||||
TopBit.setBit(OVT.getSizeInBits());
|
||||
auto TopBit = APInt::getOneBitSet(NVT.getScalarSizeInBits(),
|
||||
OVT.getScalarSizeInBits());
|
||||
Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT));
|
||||
}
|
||||
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.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 {
|
||||
%c = call <2 x i64> @llvm.cttz.v2i64(<2 x i64> %a, i1 true)
|
||||
ret <2 x i64> %c
|
||||
|
||||
; CHECK-LABEL: footz
|
||||
; CHECK: bsfq
|
||||
; CHECK: bsfq
|
||||
}
|
||||
define <2 x i64> @foolz(<2 x i64> %a) nounwind {
|
||||
%c = call <2 x i64> @llvm.ctlz.v2i64(<2 x i64> %a, i1 true)
|
||||
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 {
|
||||
%c = call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> %a)
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user