Index: lib/Analysis/ConstantFolding.cpp =================================================================== --- lib/Analysis/ConstantFolding.cpp +++ lib/Analysis/ConstantFolding.cpp @@ -1443,6 +1443,11 @@ ArrayRef Operands, const TargetLibraryInfo *TLI) { if (Operands.size() == 1) { + if (isa(Operands[0])) { + // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN + if (IntrinsicID == Intrinsic::cos) + return Constant::getNullValue(Ty); + } if (ConstantFP *Op = dyn_cast(Operands[0])) { if (IntrinsicID == Intrinsic::convert_to_fp16) { APFloat Val(Op->getValueAPF()); Index: test/Transforms/InstCombine/cos_intrinsic.ll =================================================================== --- test/Transforms/InstCombine/cos_intrinsic.ll +++ test/Transforms/InstCombine/cos_intrinsic.ll @@ -0,0 +1,28 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; This test makes sure that the undef is propagated for the cos instrinsic + +declare double @llvm.cos.f64(double %Val) +declare float @llvm.cos.f32(float %Val) + +; Function Attrs: nounwind readnone +define i32 @test1() { +; CHECK-LABEL: define i32 @test1( +; CHECK-NEXT: ret i32 0 + %1 = call double @llvm.cos.f64(double undef) + %2 = fcmp ogt double %1, 0.000000e+00 + %3 = zext i1 %2 to i32 + ret i32 %3 +} + + +; Function Attrs: nounwind readnone +define float @test2(float %d) { +; CHECK-LABEL: define float @test2( +; CHECK-NEXT: %cosval = call float @llvm.cos.f32(float %d) + %cosval = call float @llvm.cos.f32(float %d) + %cosval2 = call float @llvm.cos.f32(float undef) + %fsum = fadd float %cosval2, %cosval + ret float %fsum +; CHECK-NEXT: %fsum +; CHECK: ret float %fsum +}