diff options
Diffstat (limited to 'clang/lib/CodeGen/CGBuiltin.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f2efca8cc9c..3ebf584ac8e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -8517,6 +8517,21 @@ static Value *EmitX86Select(CodeGenFunction &CGF, return CGF.Builder.CreateSelect(Mask, Op0, Op1); } +static Value *EmitX86ScalarSelect(CodeGenFunction &CGF, + Value *Mask, Value *Op0, Value *Op1) { + // If the mask is all ones just return first argument. + if (const auto *C = dyn_cast<Constant>(Mask)) + if (C->isAllOnesValue()) + return Op0; + + llvm::VectorType *MaskTy = + llvm::VectorType::get(CGF.Builder.getInt1Ty(), + Mask->getType()->getIntegerBitWidth()); + Mask = CGF.Builder.CreateBitCast(Mask, MaskTy); + Mask = CGF.Builder.CreateExtractElement(Mask, (uint64_t)0); + return CGF.Builder.CreateSelect(Mask, Op0, Op1); +} + static Value *EmitX86MaskedCompareResult(CodeGenFunction &CGF, Value *Cmp, unsigned NumElts, Value *MaskIn) { if (MaskIn) { @@ -9884,12 +9899,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, } Value *A = Builder.CreateExtractElement(Ops[1], (uint64_t)0); Function *F = CGM.getIntrinsic(Intrinsic::sqrt, A->getType()); + A = Builder.CreateCall(F, A); Value *Src = Builder.CreateExtractElement(Ops[2], (uint64_t)0); - int MaskSize = Ops[3]->getType()->getScalarSizeInBits(); - llvm::Type *MaskTy = llvm::VectorType::get(Builder.getInt1Ty(), MaskSize); - Value *Mask = Builder.CreateBitCast(Ops[3], MaskTy); - Mask = Builder.CreateExtractElement(Mask, (uint64_t)0); - A = Builder.CreateSelect(Mask, Builder.CreateCall(F, {A}), Src); + A = EmitX86ScalarSelect(*this, Ops[3], A, Src); return Builder.CreateInsertElement(Ops[0], A, (uint64_t)0); } case X86::BI__builtin_ia32_sqrtpd256: @@ -10024,14 +10036,9 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Value *A = Builder.CreateExtractElement(Ops[0], (uint64_t)0); Value *B = Builder.CreateExtractElement(Ops[1], (uint64_t)0); Value *C = Builder.CreateExtractElement(Ops[2], (uint64_t)0); - Value *Mask = Ops[3]; Value *Div = Builder.CreateFDiv(A, B); - llvm::VectorType *MaskTy = llvm::VectorType::get(Builder.getInt1Ty(), - cast<IntegerType>(Mask->getType())->getBitWidth()); - Mask = Builder.CreateBitCast(Mask, MaskTy); - Mask = Builder.CreateExtractElement(Mask, (uint64_t)0); - Value *Select = Builder.CreateSelect(Mask, Div, C); - return Builder.CreateInsertElement(Ops[0], Select, (uint64_t)0); + Div = EmitX86ScalarSelect(*this, Ops[3], Div, C); + return Builder.CreateInsertElement(Ops[0], Div, (uint64_t)0); } // 3DNow! |