@@ -1866,26 +1866,48 @@ void Legalization::visitIntrinsicInst(llvm::IntrinsicInst& I)
18661866 break ;
18671867 case Intrinsic::copysign:
18681868 {
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 ();
18721872
18731873 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" );
18761875
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 );
18791880
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));
18821883
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));
18851886
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+ };
18881891
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);
18891911 I.replaceAllUsesWith (newValue);
18901912 I.eraseFromParent ();
18911913 }
0 commit comments