[WebAssembly][ConstantFolding] Fold fp-to-int truncation intrinsics

Constant fold both the trapping and saturating versions of the
WebAssembly truncation intrinsics. The tests are adapted from the
WebAssembly spec tests for the corresponding instructions.

Requested in PR46982.

Differential Revision: https://reviews.llvm.org/D85392
This commit is contained in:
Thomas Lively 2020-08-10 12:40:05 -07:00
parent b50a4a5bcf
commit 1da4ba1036
3 changed files with 1338 additions and 1 deletions

View File

@ -18,6 +18,7 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
@ -42,6 +43,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/IntrinsicsX86.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
@ -1469,6 +1471,11 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) {
case Intrinsic::arm_mve_vctp16:
case Intrinsic::arm_mve_vctp32:
case Intrinsic::arm_mve_vctp64:
// WebAssembly float semantics are always known
case Intrinsic::wasm_trunc_signed:
case Intrinsic::wasm_trunc_unsigned:
case Intrinsic::wasm_trunc_saturate_signed:
case Intrinsic::wasm_trunc_saturate_unsigned:
return true;
// Floating point operations cannot be folded in strictfp functions in
@ -1861,11 +1868,45 @@ static Constant *ConstantFoldScalarCall1(StringRef Name,
return ConstantInt::get(Ty->getContext(), Val.bitcastToAPInt());
}
APFloat U = Op->getValueAPF();
if (IntrinsicID == Intrinsic::wasm_trunc_signed ||
IntrinsicID == Intrinsic::wasm_trunc_unsigned ||
IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned) {
bool Saturating = IntrinsicID == Intrinsic::wasm_trunc_saturate_signed ||
IntrinsicID == Intrinsic::wasm_trunc_saturate_unsigned;
bool Signed = IntrinsicID == Intrinsic::wasm_trunc_signed ||
IntrinsicID == Intrinsic::wasm_trunc_saturate_signed;
if (U.isNaN())
return Saturating ? ConstantInt::get(Ty, 0) : nullptr;
unsigned Width = Ty->getIntegerBitWidth();
APSInt Int(Width, !Signed);
bool IsExact = false;
APFloat::opStatus Status =
U.convertToInteger(Int, APFloat::rmTowardZero, &IsExact);
if (Status == APFloat::opOK || Status == APFloat::opInexact)
return ConstantInt::get(Ty, Int);
if (!Saturating)
return nullptr;
if (U.isNegative())
return Signed ? ConstantInt::get(Ty, APInt::getSignedMinValue(Width))
: ConstantInt::get(Ty, APInt::getMinValue(Width));
else
return Signed ? ConstantInt::get(Ty, APInt::getSignedMaxValue(Width))
: ConstantInt::get(Ty, APInt::getMaxValue(Width));
}
if (!Ty->isHalfTy() && !Ty->isFloatTy() && !Ty->isDoubleTy())
return nullptr;
// Use internal versions of these intrinsics.
APFloat U = Op->getValueAPF();
if (IntrinsicID == Intrinsic::nearbyint || IntrinsicID == Intrinsic::rint) {
U.roundToIntegral(APFloat::rmNearestTiesToEven);

View File

@ -0,0 +1,686 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instsimplify -S | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
declare i32 @llvm.wasm.trunc.signed.i32.f32(float)
declare i32 @llvm.wasm.trunc.unsigned.i32.f32(float)
declare i32 @llvm.wasm.trunc.signed.i32.f64(double)
declare i32 @llvm.wasm.trunc.unsigned.i32.f64(double)
declare i64 @llvm.wasm.trunc.signed.i64.f32(float)
declare i64 @llvm.wasm.trunc.unsigned.i64.f32(float)
declare i64 @llvm.wasm.trunc.signed.i64.f64(double)
declare i64 @llvm.wasm.trunc.unsigned.i64.f64(double)
define void @test_i32_trunc_f32_s(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_f32_s(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483520, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: [[T14:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x41E0000000000000)
; CHECK-NEXT: store volatile i32 [[T14]], i32* [[P]], align 4
; CHECK-NEXT: [[T15:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xC1E0000020000000)
; CHECK-NEXT: store volatile i32 [[T15]], i32* [[P]], align 4
; CHECK-NEXT: [[T16:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7FF0000000000000)
; CHECK-NEXT: store volatile i32 [[T16]], i32* [[P]], align 4
; CHECK-NEXT: [[T17:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xFFF0000000000000)
; CHECK-NEXT: store volatile i32 [[T17]], i32* [[P]], align 4
; CHECK-NEXT: [[T18:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7FF8000000000000)
; CHECK-NEXT: store volatile i32 [[T18]], i32* [[P]], align 4
; CHECK-NEXT: [[T19:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7FFA000000000000)
; CHECK-NEXT: store volatile i32 [[T19]], i32* [[P]], align 4
; CHECK-NEXT: [[T20:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xFFF8000000000000)
; CHECK-NEXT: store volatile i32 [[T20]], i32* [[P]], align 4
; CHECK-NEXT: [[T21:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xFFFA000000000000)
; CHECK-NEXT: store volatile i32 [[T21]], i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.signed.i32.f32(float +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x36a0000000000000); 0x1p-149
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -1.0)
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xbff19999a0000000); -0x1.19999ap+0
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -1.5)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xbffe666660000000); -1.9
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -2.0)
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 2147483520.0)
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -2147483648.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 2147483648.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.signed.i32.f32(float -2147483904.0)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7ff0000000000000); inf
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xfff0000000000000); -inf
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7ff8000000000000); nan
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xfff8000000000000); -nan
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.signed.i32.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i32 %t21, i32* %p
ret void
}
define void @test_i32_trunc_f32_u(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_f32_u(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -256, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: [[T13:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x41F0000000000000)
; CHECK-NEXT: store volatile i32 [[T13]], i32* [[P]], align 4
; CHECK-NEXT: [[T14:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float -1.000000e+00)
; CHECK-NEXT: store volatile i32 [[T14]], i32* [[P]], align 4
; CHECK-NEXT: [[T15:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7FF0000000000000)
; CHECK-NEXT: store volatile i32 [[T15]], i32* [[P]], align 4
; CHECK-NEXT: [[T16:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xFFF0000000000000)
; CHECK-NEXT: store volatile i32 [[T16]], i32* [[P]], align 4
; CHECK-NEXT: [[T17:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7FF8000000000000)
; CHECK-NEXT: store volatile i32 [[T17]], i32* [[P]], align 4
; CHECK-NEXT: [[T18:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7FFA000000000000)
; CHECK-NEXT: store volatile i32 [[T18]], i32* [[P]], align 4
; CHECK-NEXT: [[T19:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xFFF8000000000000)
; CHECK-NEXT: store volatile i32 [[T19]], i32* [[P]], align 4
; CHECK-NEXT: [[T20:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xFFFA000000000000)
; CHECK-NEXT: store volatile i32 [[T20]], i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x36a0000000000000); 0x1p-149
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x3ffe666660000000); 1.9
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 2.0)
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 2147483648.0)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 4294967040.0)
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xbfecccccc0000000); -0x1.ccccccp-1
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xbfefffffe0000000); -0x1.fffffep-1
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 4294967296.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float -1.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7ff0000000000000); inf
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xfff0000000000000); -inf
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7ff8000000000000); nan
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xfff8000000000000); -nan
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.unsigned.i32.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i32 %t20, i32* %p
ret void
}
define void @test_i32_trunc_f64_s(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_f64_s(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: [[T16:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x41E0000000000000)
; CHECK-NEXT: store volatile i32 [[T16]], i32* [[P]], align 4
; CHECK-NEXT: [[T17:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xC1E0000000200000)
; CHECK-NEXT: store volatile i32 [[T17]], i32* [[P]], align 4
; CHECK-NEXT: [[T18:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7FF0000000000000)
; CHECK-NEXT: store volatile i32 [[T18]], i32* [[P]], align 4
; CHECK-NEXT: [[T19:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xFFF0000000000000)
; CHECK-NEXT: store volatile i32 [[T19]], i32* [[P]], align 4
; CHECK-NEXT: [[T20:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7FF8000000000000)
; CHECK-NEXT: store volatile i32 [[T20]], i32* [[P]], align 4
; CHECK-NEXT: [[T21:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i32 [[T21]], i32* [[P]], align 4
; CHECK-NEXT: [[T22:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xFFF8000000000000)
; CHECK-NEXT: store volatile i32 [[T22]], i32* [[P]], align 4
; CHECK-NEXT: [[T23:%.*]] = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i32 [[T23]], i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.signed.i32.f64(double +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x8010000000000001); -0x1.0000000000001p-1022
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -1.0)
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xbff199999999999a); -0x1.199999999999ap+0
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -1.5)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xbffe666666666666); -1.9
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -2.0)
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 2147483647.0)
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -2147483648.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -2147483648.9)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 2147483647.9)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 2147483648.0)
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.signed.i32.f64(double -2147483649.0)
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7ff0000000000000); inf
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xfff0000000000000); -inf
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7ff8000000000000); nan
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i32 %t21, i32* %p
%t22 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0xfff8000000000000); -nan
store volatile i32 %t22, i32* %p
%t23 = call i32 @llvm.wasm.trunc.signed.i32.f64(double 0x7ff4000000000000); -nan:0x4000000000000
store volatile i32 %t23, i32* %p
ret void
}
define void @test_i32_trunc_f64_u(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_f64_u(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 100000000, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: [[T15:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x41F0000000000000)
; CHECK-NEXT: store volatile i32 [[T15]], i32* [[P]], align 4
; CHECK-NEXT: [[T16:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double -1.000000e+00)
; CHECK-NEXT: store volatile i32 [[T16]], i32* [[P]], align 4
; CHECK-NEXT: [[T17:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 1.000000e+16)
; CHECK-NEXT: store volatile i32 [[T17]], i32* [[P]], align 4
; CHECK-NEXT: [[T18:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 1.000000e+30)
; CHECK-NEXT: store volatile i32 [[T18]], i32* [[P]], align 4
; CHECK-NEXT: [[T19:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x43E0000000000000)
; CHECK-NEXT: store volatile i32 [[T19]], i32* [[P]], align 4
; CHECK-NEXT: [[T20:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7FF0000000000000)
; CHECK-NEXT: store volatile i32 [[T20]], i32* [[P]], align 4
; CHECK-NEXT: [[T21:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xFFF0000000000000)
; CHECK-NEXT: store volatile i32 [[T21]], i32* [[P]], align 4
; CHECK-NEXT: [[T22:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7FF8000000000000)
; CHECK-NEXT: store volatile i32 [[T22]], i32* [[P]], align 4
; CHECK-NEXT: [[T23:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i32 [[T23]], i32* [[P]], align 4
; CHECK-NEXT: [[T24:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xFFF8000000000000)
; CHECK-NEXT: store volatile i32 [[T24]], i32* [[P]], align 4
; CHECK-NEXT: [[T25:%.*]] = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xFFF4000000000000)
; CHECK-NEXT: store volatile i32 [[T25]], i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x8010000000000001); -0x0.0000000000001p-1022
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x3ffe666666666666); 1.9
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 2.0)
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 2147483648.0)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 4294967295.0)
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xbfeccccccccccccd); -0x1.ccccccccccccdp-1
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xbfefffffffffffff); -0x1.fffffffffffffp-1
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 100000000.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 4294967295.9)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 4294967296.0)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double -1.0)
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 10000000000000000.0); 1e16
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 1000000000000000000000000000000.0); 1e30
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 9223372036854775808.0)
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7ff0000000000000); inf
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xfff0000000000000); -inf
store volatile i32 %t21, i32* %p
%t22 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7ff8000000000000); nan
store volatile i32 %t22, i32* %p
%t23 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i32 %t23, i32* %p
%t24 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xfff8000000000000); -nan
store volatile i32 %t24, i32* %p
%t25 = call i32 @llvm.wasm.trunc.unsigned.i32.f64(double 0xfff4000000000000); -nan:0x4000000000000
store volatile i32 %t25, i32* %p
ret void
}
define void @test_i64_trunc_f32_s(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_f32_s(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223371487098961920, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: [[T16:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x43E0000000000000)
; CHECK-NEXT: store volatile i64 [[T16]], i64* [[P]], align 8
; CHECK-NEXT: [[T17:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xC3E0000020000000)
; CHECK-NEXT: store volatile i64 [[T17]], i64* [[P]], align 8
; CHECK-NEXT: [[T18:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7FF0000000000000)
; CHECK-NEXT: store volatile i64 [[T18]], i64* [[P]], align 8
; CHECK-NEXT: [[T19:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xFFF0000000000000)
; CHECK-NEXT: store volatile i64 [[T19]], i64* [[P]], align 8
; CHECK-NEXT: [[T20:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7FF8000000000000)
; CHECK-NEXT: store volatile i64 [[T20]], i64* [[P]], align 8
; CHECK-NEXT: [[T21:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7FFA000000000000)
; CHECK-NEXT: store volatile i64 [[T21]], i64* [[P]], align 8
; CHECK-NEXT: [[T22:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xFFF8000000000000)
; CHECK-NEXT: store volatile i64 [[T22]], i64* [[P]], align 8
; CHECK-NEXT: [[T23:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xFFFA000000000000)
; CHECK-NEXT: store volatile i64 [[T23]], i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.signed.i64.f32(float +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x36a0000000000000); 0x1p-149
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -1.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xbff19999a0000000); -0x1.19999ap+0
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -1.5)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xbffe666660000000); -1.9
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -2.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 4294967296.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -4294967296.0)
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 9223371487098961920.0)
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -9223372036854775808.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 9223372036854775808.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.signed.i64.f32(float -9223373136366403584.0)
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7ff0000000000000); inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xfff0000000000000); -inf
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7ff8000000000000); nan
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xfff8000000000000); -nan
store volatile i64 %t22, i64* %p
%t23 = call i64 @llvm.wasm.trunc.signed.i64.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i64 %t23, i64* %p
ret void
}
define void @test_i64_trunc_f32_u(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_f32_u(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1099511627776, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: [[T11:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x43F0000000000000)
; CHECK-NEXT: store volatile i64 [[T11]], i64* [[P]], align 8
; CHECK-NEXT: [[T12:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float -1.000000e+00)
; CHECK-NEXT: store volatile i64 [[T12]], i64* [[P]], align 8
; CHECK-NEXT: [[T13:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7FF0000000000000)
; CHECK-NEXT: store volatile i64 [[T13]], i64* [[P]], align 8
; CHECK-NEXT: [[T14:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xFFF0000000000000)
; CHECK-NEXT: store volatile i64 [[T14]], i64* [[P]], align 8
; CHECK-NEXT: [[T15:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7FF8000000000000)
; CHECK-NEXT: store volatile i64 [[T15]], i64* [[P]], align 8
; CHECK-NEXT: [[T16:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7FFA000000000000)
; CHECK-NEXT: store volatile i64 [[T16]], i64* [[P]], align 8
; CHECK-NEXT: [[T17:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xFFF8000000000000)
; CHECK-NEXT: store volatile i64 [[T17]], i64* [[P]], align 8
; CHECK-NEXT: [[T18:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xFFFA000000000000)
; CHECK-NEXT: store volatile i64 [[T18]], i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x36a0000000000000); 0x1p-149
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 4294967296.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 18446742974197923840.0)
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xbfecccccc0000000); -0x1.ccccccp-1
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xbfefffffe0000000); -0x1.fffffep-1
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 18446744073709551616.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float -1.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7ff0000000000000); inf
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xfff0000000000000); -inf
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7ff8000000000000); nan
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xfff8000000000000); -nan
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.unsigned.i64.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i64 %t18, i64* %p
ret void
}
define void @test_i64_trunc_f64_s(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_f64_s(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854774784, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: [[T16:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x43E0000000000000)
; CHECK-NEXT: store volatile i64 [[T16]], i64* [[P]], align 8
; CHECK-NEXT: [[T17:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xC3E0000000000001)
; CHECK-NEXT: store volatile i64 [[T17]], i64* [[P]], align 8
; CHECK-NEXT: [[T18:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7FF0000000000000)
; CHECK-NEXT: store volatile i64 [[T18]], i64* [[P]], align 8
; CHECK-NEXT: [[T19:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xFFF0000000000000)
; CHECK-NEXT: store volatile i64 [[T19]], i64* [[P]], align 8
; CHECK-NEXT: [[T20:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7FF8000000000000)
; CHECK-NEXT: store volatile i64 [[T20]], i64* [[P]], align 8
; CHECK-NEXT: [[T21:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i64 [[T21]], i64* [[P]], align 8
; CHECK-NEXT: [[T22:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xFFF8000000000000)
; CHECK-NEXT: store volatile i64 [[T22]], i64* [[P]], align 8
; CHECK-NEXT: [[T23:%.*]] = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i64 [[T23]], i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.signed.i64.f64(double +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x8010000000000001); -0x1.0000000000001p-1022
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -1.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xbff199999999999a); -0x1.199999999999ap+0
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -1.5)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xbffe666666666666); -1.9
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -2.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 4294967296.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -4294967296.0)
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 9223372036854774784.0)
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -9223372036854775808.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 9223372036854775808.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.signed.i64.f64(double -9223372036854777856.0)
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7ff0000000000000); inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xfff0000000000000); -inf
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7ff8000000000000); nan
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0xfff8000000000000); -nan
store volatile i64 %t22, i64* %p
%t23 = call i64 @llvm.wasm.trunc.signed.i64.f64(double 0x7ff4000000000000); -nan:0x4000000000000
store volatile i64 %t23, i64* %p
ret void
}
define void @test_i64_trunc_f64_u(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_f64_u(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967295, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2048, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 100000000, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 10000000000000000, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: [[T15:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x43F0000000000000)
; CHECK-NEXT: store volatile i64 [[T15]], i64* [[P]], align 8
; CHECK-NEXT: [[T16:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double -1.000000e+00)
; CHECK-NEXT: store volatile i64 [[T16]], i64* [[P]], align 8
; CHECK-NEXT: [[T17:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7FF0000000000000)
; CHECK-NEXT: store volatile i64 [[T17]], i64* [[P]], align 8
; CHECK-NEXT: [[T18:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xFFF0000000000000)
; CHECK-NEXT: store volatile i64 [[T18]], i64* [[P]], align 8
; CHECK-NEXT: [[T19:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7FF8000000000000)
; CHECK-NEXT: store volatile i64 [[T19]], i64* [[P]], align 8
; CHECK-NEXT: [[T20:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7FF4000000000000)
; CHECK-NEXT: store volatile i64 [[T20]], i64* [[P]], align 8
; CHECK-NEXT: [[T21:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xFFF8000000000000)
; CHECK-NEXT: store volatile i64 [[T21]], i64* [[P]], align 8
; CHECK-NEXT: [[T22:%.*]] = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xFFF4000000000000)
; CHECK-NEXT: store volatile i64 [[T22]], i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x8010000000000001); -0x0.0000000000001p-1022
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 4294967295.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 4294967296.0)
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 18446744073709549568.0)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xbfeccccccccccccd); -0x1.ccccccccccccdp-1
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xbfefffffffffffff); -0x1.fffffffffffffp-1
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 100000000.0); 1e8
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 10000000000000000.0); 1e16
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 9223372036854775808.0);
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 18446744073709551616.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double -1.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7ff0000000000000); inf
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xfff0000000000000); -inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7ff8000000000000); nan
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xfff8000000000000); -nan
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.unsigned.i64.f64(double 0xfff4000000000000); -nan:0x4000000000000
store volatile i64 %t22, i64* %p
ret void
}

View File

@ -0,0 +1,610 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -instsimplify -S | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
declare i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float)
declare i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float)
declare i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double)
declare i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double)
declare i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float)
declare i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float)
declare i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double)
declare i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double)
define void @test_i32_trunc_sat_f32_s(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_sat_f32_s(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483520, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0x36a0000000000000); 0x1p-149
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -1.0)
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xbff19999a0000000); -0x1.19999ap+0
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -1.5)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xbffe666660000000); -1.9
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -2.0)
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 2147483520.0)
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -2147483648.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 2147483648.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float -2147483904.0)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0x7ff0000000000000); inf
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xfff0000000000000); -inf
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0x7ff8000000000000); nan
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xfff8000000000000); -nan
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i32 %t21, i32* %p
ret void
}
define void @test_i32_trunc_sat_f32_u(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_sat_f32_u(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -256, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x36a0000000000000); 0x1p-149
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x3ffe666660000000); 1.9
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 2.0)
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 2147483648.0)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 4294967040.0)
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xbfecccccc0000000); -0x1.ccccccp-1
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xbfefffffe0000000); -0x1.fffffep-1
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 4294967296.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float -1.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x7ff0000000000000); inf
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xfff0000000000000); -inf
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x7ff8000000000000); nan
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xfff8000000000000); -nan
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i32 %t20, i32* %p
ret void
}
define void @test_i32_trunc_sat_f64_s(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_sat_f64_s(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2147483647, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x8010000000000001); -0x1.0000000000001p-1022
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -1.0)
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0xbff199999999999a); -0x1.199999999999ap+0
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -1.5)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0xbffe666666666666); -1.9
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -2.0)
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 2147483647.0)
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -2147483648.0)
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 2147483648.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double -2147483649.0)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x7ff0000000000000); inf
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0xfff0000000000000); -inf
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x7ff8000000000000); nan
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0xfff8000000000000); -nan
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.saturate.signed.i32.f64(double 0x7ff4000000000000); -nan:0x4000000000000
store volatile i32 %t21, i32* %p
ret void
}
define void @test_i32_trunc_sat_f64_u(i32* %p) {
; CHECK-LABEL: @test_i32_trunc_sat_f64_u(
; CHECK-NEXT: store volatile i32 0, i32* [[P:%.*]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 2, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -2147483648, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 100000000, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 -1, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: store volatile i32 0, i32* [[P]], align 4
; CHECK-NEXT: ret void
;
%t0 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double +0.0)
store volatile i32 %t0, i32* %p
%t1 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double -0.0)
store volatile i32 %t1, i32* %p
%t2 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i32 %t2, i32* %p
%t3 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x8010000000000001); -0x0.0000000000001p-1022
store volatile i32 %t3, i32* %p
%t4 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 1.0)
store volatile i32 %t4, i32* %p
%t5 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i32 %t5, i32* %p
%t6 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 1.5)
store volatile i32 %t6, i32* %p
%t7 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x3ffe666666666666); 1.9
store volatile i32 %t7, i32* %p
%t8 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 2.0)
store volatile i32 %t8, i32* %p
%t9 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 2147483648.0)
store volatile i32 %t9, i32* %p
%t10 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 4294967295.0)
store volatile i32 %t10, i32* %p
%t11 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0xbfeccccccccccccd); -0x1.ccccccccccccdp-1
store volatile i32 %t11, i32* %p
%t12 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0xbfefffffffffffff); -0x1.fffffffffffffp-1
store volatile i32 %t12, i32* %p
%t13 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 100000000.0); 1e8
store volatile i32 %t13, i32* %p
%t14 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 4294967296.0)
store volatile i32 %t14, i32* %p
%t15 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double -1.0)
store volatile i32 %t15, i32* %p
%t16 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 10000000000000000.0); 1e16
store volatile i32 %t16, i32* %p
%t17 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 1000000000000000000000000000000.0); 1e30
store volatile i32 %t17, i32* %p
%t18 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 9223372036854775808.0)
store volatile i32 %t18, i32* %p
%t19 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x7ff0000000000000); inf
store volatile i32 %t19, i32* %p
%t20 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0xfff0000000000000); -inf
store volatile i32 %t20, i32* %p
%t21 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x7ff8000000000000); nan
store volatile i32 %t21, i32* %p
%t22 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i32 %t22, i32* %p
%t23 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0xfff8000000000000); -nan
store volatile i32 %t23, i32* %p
%t24 = call i32 @llvm.wasm.trunc.saturate.unsigned.i32.f64(double 0xfff4000000000000); -nan:0x4000000000000
store volatile i32 %t24, i32* %p
ret void
}
define void @test_i64_trunc_sat_f32_s(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_sat_f32_s(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223371487098961920, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854775807, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854775807, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0x36a0000000000000); 0x1p-149
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -1.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xbff19999a0000000); -0x1.19999ap+0
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -1.5)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xbffe666660000000); -1.9
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -2.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 4294967296.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -4294967296.0)
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 9223371487098961920.0)
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -9223372036854775808.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 9223372036854775808.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float -9223373136366403584.0)
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0x7ff0000000000000); inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xfff0000000000000); -inf
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0x7ff8000000000000); nan
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xfff8000000000000); -nan
store volatile i64 %t22, i64* %p
%t23 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i64 %t23, i64* %p
ret void
}
define void @test_i64_trunc_sat_f32_u(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_sat_f32_u(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1099511627776, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0x36a0000000000000); 0x1p-149
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xb6a0000000000000); -0x1p-149
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0x3ff19999a0000000); 0x1.19999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 4294967296.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 18446742974197923840.0)
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xbfecccccc0000000); -0x1.ccccccp-1
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xbfefffffe0000000); -0x1.fffffep-1
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 18446744073709551616.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float -1.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0x7ff0000000000000); inf
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xfff0000000000000); -inf
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0x7ff8000000000000); nan
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0x7ffa000000000000); nan:0x200000
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xfff8000000000000); -nan
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f32(float 0xfffa000000000000); -nan:0x200000
store volatile i64 %t18, i64* %p
ret void
}
define void @test_i64_trunc_sat_f64_s(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_sat_f64_s(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854774784, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854775807, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 9223372036854775807, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x8010000000000001); -0x1.0000000000001p-1022
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -1.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0xbff199999999999a); -0x1.199999999999ap+0
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -1.5)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0xbffe666666666666); -1.9
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -2.0)
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 4294967296.0)
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -4294967296.0)
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 9223372036854774784.0)
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -9223372036854775808.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 9223372036854775808.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double -9223372036854777856.0)
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x7ff0000000000000); inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0xfff0000000000000); -inf
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x7ff8000000000000); nan
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0xfff8000000000000); -nan
store volatile i64 %t22, i64* %p
%t23 = call i64 @llvm.wasm.trunc.saturate.signed.i64.f64(double 0x7ff4000000000000); -nan:0x4000000000000
store volatile i64 %t23, i64* %p
ret void
}
define void @test_i64_trunc_sat_f64_u(i64* %p) {
; CHECK-LABEL: @test_i64_trunc_sat_f64_u(
; CHECK-NEXT: store volatile i64 0, i64* [[P:%.*]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967295, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 4294967296, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -2048, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 100000000, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 10000000000000000, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -9223372036854775808, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 -1, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: store volatile i64 0, i64* [[P]], align 8
; CHECK-NEXT: ret void
;
%t0 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double +0.0)
store volatile i64 %t0, i64* %p
%t1 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double -0.0)
store volatile i64 %t1, i64* %p
%t2 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x0010000000000001); 0x0.0000000000001p-1022
store volatile i64 %t2, i64* %p
%t3 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x8010000000000001); -0x0.0000000000001p-1022
store volatile i64 %t3, i64* %p
%t4 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 1.0)
store volatile i64 %t4, i64* %p
%t5 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x3ff199999999999a); 0x1.199999999999ap+0
store volatile i64 %t5, i64* %p
%t6 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 1.5)
store volatile i64 %t6, i64* %p
%t7 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 4294967295.0)
store volatile i64 %t7, i64* %p
%t8 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 4294967296.0)
store volatile i64 %t8, i64* %p
%t9 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 18446744073709549568.0)
store volatile i64 %t9, i64* %p
%t10 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0xbfeccccccccccccd); -0x1.ccccccccccccdp-1
store volatile i64 %t10, i64* %p
%t11 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0xbfefffffffffffff); -0x1.fffffffffffffp-1
store volatile i64 %t11, i64* %p
%t12 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 100000000.0); 1e8
store volatile i64 %t12, i64* %p
%t13 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 10000000000000000.0); 1e16
store volatile i64 %t13, i64* %p
%t14 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 9223372036854775808.0);
store volatile i64 %t14, i64* %p
%t15 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 18446744073709551616.0)
store volatile i64 %t15, i64* %p
%t16 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double -1.0)
store volatile i64 %t16, i64* %p
%t17 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x7ff0000000000000); inf
store volatile i64 %t17, i64* %p
%t18 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0xfff0000000000000); -inf
store volatile i64 %t18, i64* %p
%t19 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x7ff8000000000000); nan
store volatile i64 %t19, i64* %p
%t20 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0x7ff4000000000000); nan:0x4000000000000
store volatile i64 %t20, i64* %p
%t21 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0xfff8000000000000); -nan
store volatile i64 %t21, i64* %p
%t22 = call i64 @llvm.wasm.trunc.saturate.unsigned.i64.f64(double 0xfff4000000000000); -nan:0x4000000000000
store volatile i64 %t22, i64* %p
ret void
}