mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-28 22:58:17 +00:00
Fix PR16807
- Lower signed division by constant powers-of-2 to target-independent DAG operators instead of target-dependent ones to support them better on targets where vector types are legal but shift operators on that types are illegal. E.g., on AVX, PSRAW is only available on <8 x i16> though <16 x i16> is a legal type. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192721 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d45b3c4653
commit
dc8c044a9a
@ -12467,14 +12467,24 @@ static SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) {
|
||||
(SplatValue.isPowerOf2() || (-SplatValue).isPowerOf2())) {
|
||||
unsigned lg2 = SplatValue.countTrailingZeros();
|
||||
// Splat the sign bit.
|
||||
SDValue Sz = DAG.getConstant(EltTy.getSizeInBits()-1, MVT::i32);
|
||||
SDValue SGN = getTargetVShiftNode(X86ISD::VSRAI, dl, VT, N0, Sz, DAG);
|
||||
SmallVector<SDValue, 16> Sz(NumElts,
|
||||
DAG.getConstant(EltTy.getSizeInBits() - 1,
|
||||
EltTy));
|
||||
SDValue SGN = DAG.getNode(ISD::SRA, dl, VT, N0,
|
||||
DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Sz[0],
|
||||
NumElts));
|
||||
// Add (N0 < 0) ? abs2 - 1 : 0;
|
||||
SDValue Amt = DAG.getConstant(EltTy.getSizeInBits() - lg2, MVT::i32);
|
||||
SDValue SRL = getTargetVShiftNode(X86ISD::VSRLI, dl, VT, SGN, Amt, DAG);
|
||||
SmallVector<SDValue, 16> Amt(NumElts,
|
||||
DAG.getConstant(EltTy.getSizeInBits() - lg2,
|
||||
EltTy));
|
||||
SDValue SRL = DAG.getNode(ISD::SRL, dl, VT, SGN,
|
||||
DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Amt[0],
|
||||
NumElts));
|
||||
SDValue ADD = DAG.getNode(ISD::ADD, dl, VT, N0, SRL);
|
||||
SDValue Lg2Amt = DAG.getConstant(lg2, MVT::i32);
|
||||
SDValue SRA = getTargetVShiftNode(X86ISD::VSRAI, dl, VT, ADD, Lg2Amt, DAG);
|
||||
SmallVector<SDValue, 16> Lg2Amt(NumElts, DAG.getConstant(lg2, EltTy));
|
||||
SDValue SRA = DAG.getNode(ISD::SRA, dl, VT, ADD,
|
||||
DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Lg2Amt[0],
|
||||
NumElts));
|
||||
|
||||
// If we're dividing by a positive value, we're done. Otherwise, we must
|
||||
// negate the result.
|
||||
|
18
test/CodeGen/X86/pr16807.ll
Normal file
18
test/CodeGen/X86/pr16807.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-linux-gnu -mcpu=core-avx-i | FileCheck %s
|
||||
|
||||
define <16 x i16> @f_fu(<16 x i16> %bf) {
|
||||
allocas:
|
||||
%avg.i.i = sdiv <16 x i16> %bf, <i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4, i16 4>
|
||||
ret <16 x i16> %avg.i.i
|
||||
}
|
||||
|
||||
; CHECK: f_fu
|
||||
; CHECK: psraw
|
||||
; CHECK: psrlw
|
||||
; CHECK: paddw
|
||||
; CHECK: psraw
|
||||
; CHECK: psraw
|
||||
; CHECK: psrlw
|
||||
; CHECK: paddw
|
||||
; CHECK: psraw
|
||||
; CHECK: ret
|
Loading…
x
Reference in New Issue
Block a user