Index: tests_lit/llvm2ice_tests/fpcall.ll |
diff --git a/tests_lit/llvm2ice_tests/fpcall.ll b/tests_lit/llvm2ice_tests/fpcall.ll |
new file mode 100644 |
index 0000000000000000000000000000000000000000..251a8117b5b5af7d0923461ed58de7b3ad945387 |
--- /dev/null |
+++ b/tests_lit/llvm2ice_tests/fpcall.ll |
@@ -0,0 +1,60 @@ |
+; Test that for calls returning a floating-point value, the calling |
+; ABI with respect to the x87 floating point stack is honored. In |
+; particular, the top-of-stack must be popped regardless of whether |
+; its value is used. |
+ |
+; RUN: %llvm2ice -O2 --verbose none %s \ |
+; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
+; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
+; RUN: %llvm2ice -Om1 --verbose none %s \ |
+; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \ |
+; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s |
+; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s |
+; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s |
+; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \ |
+; RUN: | FileCheck --check-prefix=DUMP %s |
+ |
+define float @dummy() { |
+entry: |
+ ret float 0.000000e+00 |
+} |
+; CHECK-LABEL: dummy |
+ |
+; The call is ignored, but the top of the FP stack still needs to be |
+; popped. |
+define i32 @ignored_fp_call() { |
+entry: |
+ %ignored = call float @dummy() |
+ ret i32 0 |
+} |
+; CHECK-LABEL: ignored_fp_call |
+; CHECK: call dummy |
+; CHECK: fstp |
+ |
+; The top of the FP stack is popped and subsequently used. |
+define i32 @converted_fp_call() { |
+entry: |
+ %fp = call float @dummy() |
+ %ret = fptosi float %fp to i32 |
+ ret i32 %ret |
+} |
+; CHECK-LABEL: converted_fp_call |
+; CHECK: call dummy |
+; CHECK: fstp |
+; CHECK: cvttss2si |
+ |
+; The top of the FP stack is ultimately passed through as the return |
+; value. Note: the translator could optimized by not popping and |
+; re-pushing, in which case the test would need to be changed. |
+define float @returned_fp_call() { |
+entry: |
+ %fp = call float @dummy() |
+ ret float %fp |
+} |
+; CHECK-LABEL: returned_fp_call |
+; CHECK: call dummy |
+; CHECK: fstp |
+; CHECK: fld |
+ |
+; ERRORS-NOT: ICE translation error |
+; DUMP-NOT: SZ |