@@ -1866,26 +1866,48 @@ void Legalization::visitIntrinsicInst(llvm::IntrinsicInst& I)
1866
1866
break ;
1867
1867
case Intrinsic::copysign:
1868
1868
{
1869
- Value* src0 = I.getArgOperand (0 );
1870
- Value* src1 = I.getArgOperand (1 );
1871
- auto srcType = src0->getType ();
1869
+ Value* const src0 = I.getArgOperand (0 );
1870
+ Value* const src1 = I.getArgOperand (1 );
1871
+ Type* const srcType = src0->getType ();
1872
1872
1873
1873
IGC_ASSERT (nullptr != srcType);
1874
- IGC_ASSERT_MESSAGE (!srcType->isVectorTy (), " Vector type not supported!" );
1875
- IGC_ASSERT_MESSAGE (srcType->isFloatingPointTy (), " llvm.copysign supports only floating-point type" );
1874
+ IGC_ASSERT_MESSAGE (srcType->getScalarType ()->isFloatingPointTy (), " llvm.copysign supports only floating-point type" );
1876
1875
1877
- auto srcTypeSize = (unsigned int )srcType->getPrimitiveSizeInBits ();
1878
- uint64_t signMask = (uint64_t )0x1 << (srcTypeSize - 1 );
1876
+ auto cpySign = [&Builder](Value* const src0, Value* const src1) {
1877
+ Type* const srcType = src0->getType ();
1878
+ const unsigned int srcTypeSize = srcType->getPrimitiveSizeInBits ();
1879
+ const uint64_t signMask = (uint64_t )0x1 << (srcTypeSize - 1 );
1879
1880
1880
- auto src0Int = Builder.CreateBitCast (src0, Builder.getIntNTy (srcTypeSize));
1881
- auto src1Int = Builder.CreateBitCast (src1, Builder.getIntNTy (srcTypeSize));
1881
+ Value* const src0Int = Builder.CreateBitCast (src0, Builder.getIntNTy (srcTypeSize));
1882
+ Value* const src1Int = Builder.CreateBitCast (src1, Builder.getIntNTy (srcTypeSize));
1882
1883
1883
- auto src0NoSign = Builder.CreateAnd (src0Int, Builder.getIntN (srcTypeSize, ~signMask));
1884
- auto src1Sign = Builder.CreateAnd (src1Int, Builder.getIntN (srcTypeSize, signMask));
1884
+ Value* const src0NoSign = Builder.CreateAnd (src0Int, Builder.getIntN (srcTypeSize, ~signMask));
1885
+ Value* const src1Sign = Builder.CreateAnd (src1Int, Builder.getIntN (srcTypeSize, signMask));
1885
1886
1886
- auto newValue = static_cast <Value*>(Builder.CreateOr (src0NoSign, src1Sign));
1887
- newValue = Builder.CreateBitCast (newValue, srcType);
1887
+ Value* newValue = static_cast <Value*>(Builder.CreateOr (src0NoSign, src1Sign));
1888
+ newValue = Builder.CreateBitCast (newValue, srcType);
1889
+ return newValue;
1890
+ };
1888
1891
1892
+ Value* newValue = nullptr ;
1893
+ if (srcType->isVectorTy ())
1894
+ {
1895
+ const unsigned int numElements = srcType->getVectorNumElements ();
1896
+ Value* dstVec = UndefValue::get (srcType);
1897
+ for (unsigned int i = 0 ; i < numElements; ++i)
1898
+ {
1899
+ Value* const src0Scalar = Builder.CreateExtractElement (src0, i);
1900
+ Value* const src1Scalar = Builder.CreateExtractElement (src1, i);
1901
+ auto newValue = cpySign (src0Scalar, src1Scalar);
1902
+ dstVec = Builder.CreateInsertElement (dstVec, newValue, i);
1903
+ }
1904
+ newValue = dstVec;
1905
+ }
1906
+ else
1907
+ {
1908
+ newValue = cpySign (src0, src1);
1909
+ }
1910
+ IGC_ASSERT (nullptr != newValue);
1889
1911
I.replaceAllUsesWith (newValue);
1890
1912
I.eraseFromParent ();
1891
1913
}
0 commit comments