Index: tests_lit/llvm2ice_tests/fp.pnacl.ll |
diff --git a/tests_lit/llvm2ice_tests/fp.pnacl.ll b/tests_lit/llvm2ice_tests/fp.pnacl.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8981c9efd680ae78b8215572f069d3facdd71807 |
--- /dev/null |
+++ b/tests_lit/llvm2ice_tests/fp.pnacl.ll |
@@ -0,0 +1,1099 @@ |
+; RUIN: %llvm2ice --verbose none %s | FileCheck %s |
+; RUIN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s |
+; RUN: %szdiff --llvm2ice=%llvm2ice %s | FileCheck --check-prefix=DUMP %s |
+ |
+@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4 |
+@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4 |
+@__tls_template_start = internal constant [0 x i8] zeroinitializer, align 8 |
+@__tls_template_alignment = internal constant [4 x i8] c"\01\00\00\00", align 4 |
+ |
+define internal i32 @doubleArgs(double %a, i32 %b, double %c) { |
+entry: |
+ ret i32 %b |
+} |
+; CHECK: doubleArgs: |
+; CHECK: mov eax, dword ptr [esp+12] |
+; CHECK-NEXT: ret |
+ |
+define internal i32 @floatArgs(float %a, i32 %b, float %c) { |
+entry: |
+ ret i32 %b |
+} |
+; CHECK: floatArgs: |
+; CHECK: mov eax, dword ptr [esp+8] |
+; CHECK-NEXT: ret |
+ |
+define internal i32 @passFpArgs(float %a, double %b, float %c, double %d, float %e, double %f) { |
+entry: |
+ %call = call i32 @ignoreFpArgsNoInline(float %a, i32 123, double %b) |
+ %call1 = call i32 @ignoreFpArgsNoInline(float %c, i32 123, double %d) |
+ %call2 = call i32 @ignoreFpArgsNoInline(float %e, i32 123, double %f) |
+ %add = add i32 %call1, %call |
+ %add3 = add i32 %add, %call2 |
+ ret i32 %add3 |
+} |
+; CHECK: passFpArgs: |
+; CHECK: push 123 |
+; CHECK: call ignoreFpArgsNoInline |
+; CHECK: push 123 |
+; CHECK: call ignoreFpArgsNoInline |
+; CHECK: push 123 |
+; CHECK: call ignoreFpArgsNoInline |
+ |
+declare i32 @ignoreFpArgsNoInline(float, i32, double) |
+ |
+define internal i32 @passFpConstArg(float %a, double %b) { |
+entry: |
+ %call = call i32 @ignoreFpArgsNoInline(float %a, i32 123, double 2.340000e+00) |
+ ret i32 %call |
+} |
+; CHECK: passFpConstArg: |
+; CHECK: push 123 |
+; CHECK: call ignoreFpArgsNoInline |
+ |
+define internal float @returnFloatArg(float %a) { |
+entry: |
+ ret float %a |
+} |
+; CHECK: returnFloatArg: |
+; CHECK: fld dword ptr [esp |
+ |
+define internal double @returnDoubleArg(double %a) { |
+entry: |
+ ret double %a |
+} |
+; CHECK: returnDoubleArg: |
+; CHECK: fld qword ptr [esp |
+ |
+define internal float @returnFloatConst() { |
+entry: |
+ ret float 0x3FF3AE1480000000 |
+} |
+; CHECK: returnFloatConst: |
+; CHECK: fld |
+ |
+define internal double @returnDoubleConst() { |
+entry: |
+ ret double 1.230000e+00 |
+} |
+; CHECK: returnDoubleConst: |
+; CHECK: fld |
+ |
+define internal float @addFloat(float %a, float %b) { |
+entry: |
+ %add = fadd float %a, %b |
+ ret float %add |
+} |
+; CHECK: addFloat: |
+; CHECK: addss |
+; CHECK: fld |
+ |
+define internal double @addDouble(double %a, double %b) { |
+entry: |
+ %add = fadd double %a, %b |
+ ret double %add |
+} |
+; CHECK: addDouble: |
+; CHECK: addsd |
+; CHECK: fld |
+ |
+define internal float @subFloat(float %a, float %b) { |
+entry: |
+ %sub = fsub float %a, %b |
+ ret float %sub |
+} |
+; CHECK: subFloat: |
+; CHECK: subss |
+; CHECK: fld |
+ |
+define internal double @subDouble(double %a, double %b) { |
+entry: |
+ %sub = fsub double %a, %b |
+ ret double %sub |
+} |
+; CHECK: subDouble: |
+; CHECK: subsd |
+; CHECK: fld |
+ |
+define internal float @mulFloat(float %a, float %b) { |
+entry: |
+ %mul = fmul float %a, %b |
+ ret float %mul |
+} |
+; CHECK: mulFloat: |
+; CHECK: mulss |
+; CHECK: fld |
+ |
+define internal double @mulDouble(double %a, double %b) { |
+entry: |
+ %mul = fmul double %a, %b |
+ ret double %mul |
+} |
+; CHECK: mulDouble: |
+; CHECK: mulsd |
+; CHECK: fld |
+ |
+define internal float @divFloat(float %a, float %b) { |
+entry: |
+ %div = fdiv float %a, %b |
+ ret float %div |
+} |
+; CHECK: divFloat: |
+; CHECK: divss |
+; CHECK: fld |
+ |
+define internal double @divDouble(double %a, double %b) { |
+entry: |
+ %div = fdiv double %a, %b |
+ ret double %div |
+} |
+; CHECK: divDouble: |
+; CHECK: divsd |
+; CHECK: fld |
+ |
+define internal float @remFloat(float %a, float %b) { |
+entry: |
+ %div = frem float %a, %b |
+ ret float %div |
+} |
+; CHECK: remFloat: |
+; CHECK: call fmodf |
+ |
+define internal double @remDouble(double %a, double %b) { |
+entry: |
+ %div = frem double %a, %b |
+ ret double %div |
+} |
+; CHECK: remDouble: |
+; CHECK: call fmod |
+ |
+define internal float @fptrunc(double %a) { |
+entry: |
+ %conv = fptrunc double %a to float |
+ ret float %conv |
+} |
+; CHECK: fptrunc: |
+; CHECK: cvtsd2ss |
+; CHECK: fld |
+ |
+define internal double @fpext(float %a) { |
+entry: |
+ %conv = fpext float %a to double |
+ ret double %conv |
+} |
+; CHECK: fpext: |
+; CHECK: cvtss2sd |
+; CHECK: fld |
+ |
+define internal i64 @doubleToSigned64(double %a) { |
+entry: |
+ %conv = fptosi double %a to i64 |
+ ret i64 %conv |
+} |
+; CHECK: doubleToSigned64: |
+; CHECK: call cvtdtosi64 |
+ |
+define internal i64 @floatToSigned64(float %a) { |
+entry: |
+ %conv = fptosi float %a to i64 |
+ ret i64 %conv |
+} |
+; CHECK: floatToSigned64: |
+; CHECK: call cvtftosi64 |
+ |
+define internal i64 @doubleToUnsigned64(double %a) { |
+entry: |
+ %conv = fptoui double %a to i64 |
+ ret i64 %conv |
+} |
+; CHECK: doubleToUnsigned64: |
+; CHECK: call cvtdtoui64 |
+ |
+define internal i64 @floatToUnsigned64(float %a) { |
+entry: |
+ %conv = fptoui float %a to i64 |
+ ret i64 %conv |
+} |
+; CHECK: floatToUnsigned64: |
+; CHECK: call cvtftoui64 |
+ |
+define internal i32 @doubleToSigned32(double %a) { |
+entry: |
+ %conv = fptosi double %a to i32 |
+ ret i32 %conv |
+} |
+; CHECK: doubleToSigned32: |
+; CHECK: cvtsd2si |
+ |
+define internal i32 @floatToSigned32(float %a) { |
+entry: |
+ %conv = fptosi float %a to i32 |
+ ret i32 %conv |
+} |
+; CHECK: floatToSigned32: |
+; CHECK: cvtss2si |
+ |
+define internal i32 @doubleToUnsigned32(double %a) { |
+entry: |
+ %conv = fptoui double %a to i32 |
+ ret i32 %conv |
+} |
+; CHECK: doubleToUnsigned32: |
+; CHECK: call cvtdtoui32 |
+ |
+define internal i32 @floatToUnsigned32(float %a) { |
+entry: |
+ %conv = fptoui float %a to i32 |
+ ret i32 %conv |
+} |
+; CHECK: floatToUnsigned32: |
+; CHECK: call cvtftoui32 |
+ |
+define internal i32 @doubleToSigned16(double %a) { |
+entry: |
+ %conv = fptosi double %a to i16 |
+ %conv.ret_ext = sext i16 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: doubleToSigned16: |
+; CHECK: cvtsd2si |
+; CHECK: movsx |
+ |
+define internal i32 @floatToSigned16(float %a) { |
+entry: |
+ %conv = fptosi float %a to i16 |
+ %conv.ret_ext = sext i16 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: floatToSigned16: |
+; CHECK: cvtss2si |
+; CHECK: movsx |
+ |
+define internal i32 @doubleToUnsigned16(double %a) { |
+entry: |
+ %conv = fptoui double %a to i16 |
+ %conv.ret_ext = zext i16 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: doubleToUnsigned16: |
+; CHECK: cvtsd2si |
+; CHECK: movzx |
+ |
+define internal i32 @floatToUnsigned16(float %a) { |
+entry: |
+ %conv = fptoui float %a to i16 |
+ %conv.ret_ext = zext i16 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: floatToUnsigned16: |
+; CHECK: cvtss2si |
+; CHECK: movzx |
+ |
+define internal i32 @doubleToSigned8(double %a) { |
+entry: |
+ %conv = fptosi double %a to i8 |
+ %conv.ret_ext = sext i8 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: doubleToSigned8: |
+; CHECK: cvtsd2si |
+; CHECK: movsx |
+ |
+define internal i32 @floatToSigned8(float %a) { |
+entry: |
+ %conv = fptosi float %a to i8 |
+ %conv.ret_ext = sext i8 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: floatToSigned8: |
+; CHECK: cvtss2si |
+; CHECK: movsx |
+ |
+define internal i32 @doubleToUnsigned8(double %a) { |
+entry: |
+ %conv = fptoui double %a to i8 |
+ %conv.ret_ext = zext i8 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: doubleToUnsigned8: |
+; CHECK: cvtsd2si |
+; CHECK: movzx |
+ |
+define internal i32 @floatToUnsigned8(float %a) { |
+entry: |
+ %conv = fptoui float %a to i8 |
+ %conv.ret_ext = zext i8 %conv to i32 |
+ ret i32 %conv.ret_ext |
+} |
+; CHECK: floatToUnsigned8: |
+; CHECK: cvtss2si |
+; CHECK: movzx |
+ |
+define internal i32 @doubleToUnsigned1(double %a) { |
+entry: |
+ %tobool = fptoui double %a to i1 |
+ %tobool.ret_ext = zext i1 %tobool to i32 |
+ ret i32 %tobool.ret_ext |
+} |
+; CHECK: doubleToUnsigned1: |
+; CHECK: cvtsd2si |
+; CHECK: and eax, 1 |
+ |
+define internal i32 @floatToUnsigned1(float %a) { |
+entry: |
+ %tobool = fptoui float %a to i1 |
+ %tobool.ret_ext = zext i1 %tobool to i32 |
+ ret i32 %tobool.ret_ext |
+} |
+; CHECK: floatToUnsigned1: |
+; CHECK: cvtss2si |
+; CHECK: and eax, 1 |
+ |
+define internal double @signed64ToDouble(i64 %a) { |
+entry: |
+ %conv = sitofp i64 %a to double |
+ ret double %conv |
+} |
+; CHECK: signed64ToDouble: |
+; CHECK: call cvtsi64tod |
+; CHECK: fstp |
+ |
+define internal float @signed64ToFloat(i64 %a) { |
+entry: |
+ %conv = sitofp i64 %a to float |
+ ret float %conv |
+} |
+; CHECK: signed64ToFloat: |
+; CHECK: call cvtsi64tof |
+; CHECK: fstp |
+ |
+define internal double @unsigned64ToDouble(i64 %a) { |
+entry: |
+ %conv = uitofp i64 %a to double |
+ ret double %conv |
+} |
+; CHECK: unsigned64ToDouble: |
+; CHECK: call cvtui64tod |
+; CHECK: fstp |
+ |
+define internal float @unsigned64ToFloat(i64 %a) { |
+entry: |
+ %conv = uitofp i64 %a to float |
+ ret float %conv |
+} |
+; CHECK: unsigned64ToFloat: |
+; CHECK: call cvtui64tof |
+; CHECK: fstp |
+ |
+define internal double @signed32ToDouble(i32 %a) { |
+entry: |
+ %conv = sitofp i32 %a to double |
+ ret double %conv |
+} |
+; CHECK: signed32ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @signed32ToFloat(i32 %a) { |
+entry: |
+ %conv = sitofp i32 %a to float |
+ ret float %conv |
+} |
+; CHECK: signed32ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal double @unsigned32ToDouble(i32 %a) { |
+entry: |
+ %conv = uitofp i32 %a to double |
+ ret double %conv |
+} |
+; CHECK: unsigned32ToDouble: |
+; CHECK: call cvtui32tod |
+; CHECK: fstp |
+ |
+define internal float @unsigned32ToFloat(i32 %a) { |
+entry: |
+ %conv = uitofp i32 %a to float |
+ ret float %conv |
+} |
+; CHECK: unsigned32ToFloat: |
+; CHECK: call cvtui32tof |
+; CHECK: fstp |
+ |
+define internal double @signed16ToDouble(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i16 |
+ %conv = sitofp i16 %a.arg_trunc to double |
+ ret double %conv |
+} |
+; CHECK: signed16ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @signed16ToFloat(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i16 |
+ %conv = sitofp i16 %a.arg_trunc to float |
+ ret float %conv |
+} |
+; CHECK: signed16ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal double @unsigned16ToDouble(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i16 |
+ %conv = uitofp i16 %a.arg_trunc to double |
+ ret double %conv |
+} |
+; CHECK: unsigned16ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @unsigned16ToFloat(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i16 |
+ %conv = uitofp i16 %a.arg_trunc to float |
+ ret float %conv |
+} |
+; CHECK: unsigned16ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal double @signed8ToDouble(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i8 |
+ %conv = sitofp i8 %a.arg_trunc to double |
+ ret double %conv |
+} |
+; CHECK: signed8ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @signed8ToFloat(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i8 |
+ %conv = sitofp i8 %a.arg_trunc to float |
+ ret float %conv |
+} |
+; CHECK: signed8ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal double @unsigned8ToDouble(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i8 |
+ %conv = uitofp i8 %a.arg_trunc to double |
+ ret double %conv |
+} |
+; CHECK: unsigned8ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @unsigned8ToFloat(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i8 |
+ %conv = uitofp i8 %a.arg_trunc to float |
+ ret float %conv |
+} |
+; CHECK: unsigned8ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal double @unsigned1ToDouble(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i1 |
+ %conv = uitofp i1 %a.arg_trunc to double |
+ ret double %conv |
+} |
+; CHECK: unsigned1ToDouble: |
+; CHECK: cvtsi2sd |
+; CHECK: fld |
+ |
+define internal float @unsigned1ToFloat(i32 %a) { |
+entry: |
+ %a.arg_trunc = trunc i32 %a to i1 |
+ %conv = uitofp i1 %a.arg_trunc to float |
+ ret float %conv |
+} |
+; CHECK: unsigned1ToFloat: |
+; CHECK: cvtsi2ss |
+; CHECK: fld |
+ |
+define internal void @fcmpEq(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp oeq float %a, %b |
+ br i1 %cmp, label %if.then, label %if.end |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %if.then, %entry |
+ %cmp1 = fcmp oeq double %c, %d |
+ br i1 %cmp1, label %if.then2, label %if.end3 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.then2, %if.end |
+ ret void |
+} |
+; CHECK: fcmpEq: |
+; CHECK: ucomiss |
+; CHECK: jne . |
+; CHECK-NEXT: jp . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: jne . |
+; CHECK-NEXT: jp . |
+; CHECK: call func |
+ |
+declare void @func() |
+ |
+define internal void @fcmpNe(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp une float %a, %b |
+ br i1 %cmp, label %if.then, label %if.end |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %if.then, %entry |
+ %cmp1 = fcmp une double %c, %d |
+ br i1 %cmp1, label %if.then2, label %if.end3 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.then2, %if.end |
+ ret void |
+} |
+; CHECK: fcmpNe: |
+; CHECK: ucomiss |
+; CHECK: jne . |
+; CHECK-NEXT: jp . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: jne . |
+; CHECK-NEXT: jp . |
+; CHECK: call func |
+ |
+define internal void @fcmpGt(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp ogt float %a, %b |
+ br i1 %cmp, label %if.then, label %if.end |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %if.then, %entry |
+ %cmp1 = fcmp ogt double %c, %d |
+ br i1 %cmp1, label %if.then2, label %if.end3 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.then2, %if.end |
+ ret void |
+} |
+; CHECK: fcmpGt: |
+; CHECK: ucomiss |
+; CHECK: ja . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: ja . |
+; CHECK: call func |
+ |
+define internal void @fcmpGe(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp ult float %a, %b |
+ br i1 %cmp, label %if.end, label %if.then |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %entry, %if.then |
+ %cmp1 = fcmp ult double %c, %d |
+ br i1 %cmp1, label %if.end3, label %if.then2 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.end, %if.then2 |
+ ret void |
+} |
+; CHECK: fcmpGe: |
+; CHECK: ucomiss |
+; CHECK: jb . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: jb . |
+; CHECK: call func |
+ |
+define internal void @fcmpLt(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp olt float %a, %b |
+ br i1 %cmp, label %if.then, label %if.end |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %if.then, %entry |
+ %cmp1 = fcmp olt double %c, %d |
+ br i1 %cmp1, label %if.then2, label %if.end3 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.then2, %if.end |
+ ret void |
+} |
+; CHECK: fcmpLt: |
+; CHECK: ucomiss |
+; CHECK: ja . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: ja . |
+; CHECK: call func |
+ |
+define internal void @fcmpLe(float %a, float %b, double %c, double %d) { |
+entry: |
+ %cmp = fcmp ugt float %a, %b |
+ br i1 %cmp, label %if.end, label %if.then |
+ |
+if.then: ; preds = %entry |
+ call void @func() |
+ br label %if.end |
+ |
+if.end: ; preds = %entry, %if.then |
+ %cmp1 = fcmp ugt double %c, %d |
+ br i1 %cmp1, label %if.end3, label %if.then2 |
+ |
+if.then2: ; preds = %if.end |
+ call void @func() |
+ br label %if.end3 |
+ |
+if.end3: ; preds = %if.end, %if.then2 |
+ ret void |
+} |
+; CHECK: fcmpLe: |
+; CHECK: ucomiss |
+; CHECK: jb . |
+; CHECK: call func |
+; CHECK: ucomisd |
+; CHECK: jb . |
+; CHECK: call func |
+ |
+define internal i32 @fcmpFalseFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp false float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpFalseFloat: |
+; CHECK: mov {{.*}}, 0 |
+ |
+define internal i32 @fcmpFalseDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp false double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpFalseDouble: |
+; CHECK: mov {{.*}}, 0 |
+ |
+define internal i32 @fcmpOeqFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp oeq float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOeqFloat: |
+; CHECK: ucomiss |
+; CHECK: jne . |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpOeqDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp oeq double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOeqDouble: |
+; CHECK: ucomisd |
+; CHECK: jne . |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpOgtFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ogt float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOgtFloat: |
+; CHECK: ucomiss |
+; CHECK: ja . |
+ |
+define internal i32 @fcmpOgtDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ogt double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOgtDouble: |
+; CHECK: ucomisd |
+; CHECK: ja . |
+ |
+define internal i32 @fcmpOgeFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp oge float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOgeFloat: |
+; CHECK: ucomiss |
+; CHECK: jae . |
+ |
+define internal i32 @fcmpOgeDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp oge double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOgeDouble: |
+; CHECK: ucomisd |
+; CHECK: jae . |
+ |
+define internal i32 @fcmpOltFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp olt float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOltFloat: |
+; CHECK: ucomiss |
+; CHECK: ja . |
+ |
+define internal i32 @fcmpOltDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp olt double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOltDouble: |
+; CHECK: ucomisd |
+; CHECK: ja . |
+ |
+define internal i32 @fcmpOleFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ole float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOleFloat: |
+; CHECK: ucomiss |
+; CHECK: jae . |
+ |
+define internal i32 @fcmpOleDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ole double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOleDouble: |
+; CHECK: ucomisd |
+; CHECK: jae . |
+ |
+define internal i32 @fcmpOneFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp one float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOneFloat: |
+; CHECK: ucomiss |
+; CHECK: jne . |
+ |
+define internal i32 @fcmpOneDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp one double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOneDouble: |
+; CHECK: ucomisd |
+; CHECK: jne . |
+ |
+define internal i32 @fcmpOrdFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ord float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOrdFloat: |
+; CHECK: ucomiss |
+; CHECK: jnp . |
+ |
+define internal i32 @fcmpOrdDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ord double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpOrdDouble: |
+; CHECK: ucomisd |
+; CHECK: jnp . |
+ |
+define internal i32 @fcmpUeqFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ueq float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUeqFloat: |
+; CHECK: ucomiss |
+; CHECK: je . |
+ |
+define internal i32 @fcmpUeqDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ueq double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUeqDouble: |
+; CHECK: ucomisd |
+; CHECK: je . |
+ |
+define internal i32 @fcmpUgtFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ugt float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUgtFloat: |
+; CHECK: ucomiss |
+; CHECK: jb . |
+ |
+define internal i32 @fcmpUgtDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ugt double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUgtDouble: |
+; CHECK: ucomisd |
+; CHECK: jb . |
+ |
+define internal i32 @fcmpUgeFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp uge float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUgeFloat: |
+; CHECK: ucomiss |
+; CHECK: jbe . |
+ |
+define internal i32 @fcmpUgeDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp uge double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUgeDouble: |
+; CHECK: ucomisd |
+; CHECK: jbe . |
+ |
+define internal i32 @fcmpUltFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ult float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUltFloat: |
+; CHECK: ucomiss |
+; CHECK: jb . |
+ |
+define internal i32 @fcmpUltDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ult double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUltDouble: |
+; CHECK: ucomisd |
+; CHECK: jb . |
+ |
+define internal i32 @fcmpUleFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp ule float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUleFloat: |
+; CHECK: ucomiss |
+; CHECK: jbe . |
+ |
+define internal i32 @fcmpUleDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp ule double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUleDouble: |
+; CHECK: ucomisd |
+; CHECK: jbe . |
+ |
+define internal i32 @fcmpUneFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp une float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUneFloat: |
+; CHECK: ucomiss |
+; CHECK: jne . |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpUneDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp une double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUneDouble: |
+; CHECK: ucomisd |
+; CHECK: jne . |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpUnoFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp uno float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUnoFloat: |
+; CHECK: ucomiss |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpUnoDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp uno double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpUnoDouble: |
+; CHECK: ucomisd |
+; CHECK: jp . |
+ |
+define internal i32 @fcmpTrueFloat(float %a, float %b) { |
+entry: |
+ %cmp = fcmp true float %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpTrueFloat: |
+; CHECK: mov {{.*}}, 1 |
+ |
+define internal i32 @fcmpTrueDouble(double %a, double %b) { |
+entry: |
+ %cmp = fcmp true double %a, %b |
+ %cmp.ret_ext = zext i1 %cmp to i32 |
+ ret i32 %cmp.ret_ext |
+} |
+; CHECK: fcmpTrueDouble: |
+; CHECK: mov {{.*}}, 1 |
+ |
+define internal float @loadFloat(i32 %a) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to float* |
+ %v0 = load float* %a.asptr, align 4 |
+ ret float %v0 |
+} |
+; CHECK: loadFloat: |
+; CHECK: movss |
+; CHECK: fld |
+ |
+define internal double @loadDouble(i32 %a) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to double* |
+ %v0 = load double* %a.asptr, align 8 |
+ ret double %v0 |
+} |
+; CHECK: loadDouble: |
+; CHECK: movsd |
+; CHECK: fld |
+ |
+define internal void @storeFloat(i32 %a, float %value) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to float* |
+ store float %value, float* %a.asptr, align 4 |
+ ret void |
+} |
+; CHECK: storeFloat: |
+; CHECK: movss |
+ |
+define internal void @storeDouble(i32 %a, double %value) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to double* |
+ store double %value, double* %a.asptr, align 8 |
+ ret void |
+} |
+; CHECK: storeDouble: |
+; CHECK: movsd |
+ |
+define internal void @storeFloatConst(i32 %a) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to float* |
+ store float 0x3FF3AE1480000000, float* %a.asptr, align 4 |
+ ret void |
+} |
+; CHECK: storeFloatConst: |
+; CHECK: mov |
+; CHECK: mov |
+ |
+define internal void @storeDoubleConst(i32 %a) { |
+entry: |
+ %a.asptr = inttoptr i32 %a to double* |
+ store double 1.230000e+00, double* %a.asptr, align 8 |
+ ret void |
+} |
+; CHECK: storeDoubleConst: |
+; CHECK: mov |
+; CHECK: mov |
+ |
+define internal float @selectFloatVarVar(float %a, float %b) { |
+entry: |
+ %cmp = fcmp olt float %a, %b |
+ %cond = select i1 %cmp, float %a, float %b |
+ ret float %cond |
+} |
+; CHECK: selectFloatVarVar: |
+; CHECK: ucomiss |
+; CHECK: ja . |
+; CHECK: fld |
+ |
+define internal double @selectDoubleVarVar(double %a, double %b) { |
+entry: |
+ %cmp = fcmp olt double %a, %b |
+ %cond = select i1 %cmp, double %a, double %b |
+ ret double %cond |
+} |
+; CHECK: selectDoubleVarVar: |
+; CHECK: ucomisd |
+; CHECK: ja . |
+; CHECK: fld |
+ |
+; ERRORS-NOT: ICE translation error |
+; DUMP-NOT: SZ |