@@ -17392,14 +17392,22 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
17392
17392
case AMDGPU::BI__builtin_amdgcn_log_clampf:
17393
17393
return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp);
17394
17394
case AMDGPU::BI__builtin_amdgcn_ldexp:
17395
- case AMDGPU::BI__builtin_amdgcn_ldexpf:
17396
- case AMDGPU::BI__builtin_amdgcn_ldexph: {
17395
+ case AMDGPU::BI__builtin_amdgcn_ldexpf: {
17397
17396
llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
17398
17397
llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
17399
17398
llvm::Function *F =
17400
17399
CGM.getIntrinsic(Intrinsic::ldexp, {Src0->getType(), Src1->getType()});
17401
17400
return Builder.CreateCall(F, {Src0, Src1});
17402
17401
}
17402
+ case AMDGPU::BI__builtin_amdgcn_ldexph: {
17403
+ // The raw instruction has a different behavior for out of bounds exponent
17404
+ // values (implicit truncation instead of saturate to short_min/short_max).
17405
+ llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
17406
+ llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
17407
+ llvm::Function *F =
17408
+ CGM.getIntrinsic(Intrinsic::ldexp, {Src0->getType(), Int16Ty});
17409
+ return Builder.CreateCall(F, {Src0, Builder.CreateTrunc(Src1, Int16Ty)});
17410
+ }
17403
17411
case AMDGPU::BI__builtin_amdgcn_frexp_mant:
17404
17412
case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
17405
17413
case AMDGPU::BI__builtin_amdgcn_frexp_manth:
0 commit comments