AMDGPU: Constant folding for frexp_mant

llvm-svn: 264943
This commit is contained in:
Matt Arsenault 2016-03-30 22:28:26 +00:00
parent a8305830db
commit 5cd4f8f89f
2 changed files with 169 additions and 0 deletions

View File

@ -1846,6 +1846,20 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
break;
}
case Intrinsic::amdgcn_frexp_mant: {
Value *Src = II->getArgOperand(0);
if (const ConstantFP *C = dyn_cast<ConstantFP>(Src)) {
int Exp;
APFloat Significand = frexp(C->getValueAPF(), Exp,
APFloat::rmNearestTiesToEven);
return replaceInstUsesWith(CI, ConstantFP::get(II->getContext(),
Significand));
} else if (isa<UndefValue>(Src))
return replaceInstUsesWith(CI, Src);
break;
}
case Intrinsic::stackrestore: {
// If the save is right next to the restore, remove the restore. This can
// happen when variable allocas are DCE'd.

View File

@ -1,8 +1,13 @@
; RUN: opt -instcombine -S < %s | FileCheck %s
; --------------------------------------------------------------------
; llvm.amdgcn.rcp
; --------------------------------------------------------------------
declare float @llvm.amdgcn.rcp.f32(float) nounwind readnone
declare double @llvm.amdgcn.rcp.f64(double) nounwind readnone
; CHECK-LABEL: @test_constant_fold_rcp_f32_1
; CHECK-NEXT: ret float 1.000000e+00
define float @test_constant_fold_rcp_f32_1() nounwind {
@ -45,3 +50,153 @@ define double @test_constant_fold_rcp_f64_43() nounwind {
ret double %val
}
; --------------------------------------------------------------------
; llvm.amdgcn.frexp.mant
; --------------------------------------------------------------------
declare float @llvm.amdgcn.frexp.mant.f32(float) nounwind readnone
declare double @llvm.amdgcn.frexp.mant.f64(double) nounwind readnone
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_undef(
; CHECK-NEXT: ret float undef
define float @test_constant_fold_frexp_mant_f32_undef() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float undef)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_undef(
; CHECK-NEXT: ret double undef
define double @test_constant_fold_frexp_mant_f64_undef() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double undef)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_0(
; CHECK-NEXT: ret float 0.000000e+00
define float @test_constant_fold_frexp_mant_f32_0() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0.0)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_0(
; CHECK-NEXT: ret double 0.000000e+00
define double @test_constant_fold_frexp_mant_f64_0() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 0.0)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_n0(
; CHECK-NEXT: ret float -0.000000e+00
define float @test_constant_fold_frexp_mant_f32_n0() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float -0.0)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_n0(
; CHECK-NEXT: ret double -0.000000e+00
define double @test_constant_fold_frexp_mant_f64_n0() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double -0.0)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_1(
; CHECK-NEXT: ret float 5.000000e-01
define float @test_constant_fold_frexp_mant_f32_1() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 1.0)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_1(
; CHECK-NEXT: ret double 5.000000e-01
define double @test_constant_fold_frexp_mant_f64_1() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 1.0)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_n1(
; CHECK-NEXT: ret float -5.000000e-01
define float @test_constant_fold_frexp_mant_f32_n1() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float -1.0)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_n1(
; CHECK-NEXT: ret double -5.000000e-01
define double @test_constant_fold_frexp_mant_f64_n1() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double -1.0)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_nan(
; CHECK-NEXT: ret float 0x7FF8000000000000
define float @test_constant_fold_frexp_mant_f32_nan() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0x7FF8000000000000)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_nan(
; CHECK-NEXT: ret double 0x7FF8000000000000
define double @test_constant_fold_frexp_mant_f64_nan() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 0x7FF8000000000000)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_inf(
; CHECK-NEXT: ret float 0x7FF0000000000000
define float @test_constant_fold_frexp_mant_f32_inf() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0x7FF0000000000000)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_inf(
; CHECK-NEXT: ret double 0x7FF0000000000000
define double @test_constant_fold_frexp_mant_f64_inf() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 0x7FF0000000000000)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_ninf(
; CHECK-NEXT: ret float 0xFFF0000000000000
define float @test_constant_fold_frexp_mant_f32_ninf() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0xFFF0000000000000)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_ninf(
; CHECK-NEXT: ret double 0xFFF0000000000000
define double @test_constant_fold_frexp_mant_f64_ninf() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 0xFFF0000000000000)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_max_num(
; CHECK-NEXT: ret float 0x3FEFFFFFE0000000
define float @test_constant_fold_frexp_mant_f32_max_num() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0x47EFFFFFE0000000)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_max_num(
; CHECK-NEXT: ret double 0x3FEFFFFFFFFFFFFF
define double @test_constant_fold_frexp_mant_f64_max_num() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 0x7FEFFFFFFFFFFFFF)
ret double %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f32_min_num(
; CHECK-NEXT: ret float 5.000000e-01
define float @test_constant_fold_frexp_mant_f32_min_num() nounwind {
%val = call float @llvm.amdgcn.frexp.mant.f32(float 0x36A0000000000000)
ret float %val
}
; CHECK-LABEL: @test_constant_fold_frexp_mant_f64_min_num(
; CHECK-NEXT: ret double 5.000000e-01
define double @test_constant_fold_frexp_mant_f64_min_num() nounwind {
%val = call double @llvm.amdgcn.frexp.mant.f64(double 4.940656e-324)
ret double %val
}