diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-24 19:17:53 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-24 19:17:53 +0000 |
| commit | 02a336801959d4fc2ea0657d4489596e1ecbfee0 (patch) | |
| tree | 776cc4ed9ad3080c3c6afbb0ffb73177c40292e8 /test/CodeGen | |
| parent | 7c71d32ab52480cb7bfd9f951450060263a5b9e7 (diff) | |
Notes
Diffstat (limited to 'test/CodeGen')
| -rw-r--r-- | test/CodeGen/AArch64/ldst-opt-dbg-limit.mir | 133 | ||||
| -rw-r--r-- | test/CodeGen/AArch64/ldst-opt.mir | 132 | ||||
| -rw-r--r-- | test/CodeGen/Thumb2/float-intrinsics-double.ll | 2 | ||||
| -rw-r--r-- | test/CodeGen/Thumb2/float-intrinsics-float.ll | 2 | ||||
| -rw-r--r-- | test/CodeGen/Thumb2/intrinsics-cc.ll | 41 | ||||
| -rw-r--r-- | test/CodeGen/X86/sse1.ll | 133 |
6 files changed, 308 insertions, 135 deletions
diff --git a/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir b/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir deleted file mode 100644 index 45542cae98fa..000000000000 --- a/test/CodeGen/AArch64/ldst-opt-dbg-limit.mir +++ /dev/null @@ -1,133 +0,0 @@ -# RUN: llc -run-pass=aarch64-ldst-opt %s -o - 2>&1 | FileCheck %s ---- | - target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" - target triple = "aarch64--linux-gnu" - - ; Function Attrs: nounwind - define i16 @promote-load-from-store(i32* %dst, i32 %x) #0 { - store i32 %x, i32* %dst - %dst16 = bitcast i32* %dst to i16* - %dst1 = getelementptr inbounds i16, i16* %dst16, i32 1 - %x16 = load i16, i16* %dst1 - ret i16 %x16 - } - - ; Function Attrs: nounwind - define void @store-pair(i32* %dst, i32 %x, i32 %y) #0 { - %dst01 = bitcast i32* %dst to i32* - %dst1 = getelementptr inbounds i32, i32* %dst, i32 1 - store i32 %x, i32* %dst01 - store i32 %x, i32* %dst1 - ret void - } - - attributes #0 = { nounwind } - -... ---- -name: promote-load-from-store -alignment: 2 -exposesReturnsTwice: false -tracksRegLiveness: true -liveins: - - { reg: '%x0' } - - { reg: '%w1' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 0 - adjustsStack: false - hasCalls: false - maxCallFrameSize: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false -body: | - bb.0 (%ir-block.0): - liveins: %w1, %x0, %lr - - STRWui killed %w1, %x0, 0 :: (store 4 into %ir.dst) - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - %w0 = LDRHHui killed %x0, 1 :: (load 2 from %ir.dst1) - RET %lr, implicit %w0 - -... -# CHECK-LABEL: name: promote-load-from-store -# CHECK: STRWui %w1 -# CHECK: UBFMWri %w1 ---- -name: store-pair -alignment: 2 -exposesReturnsTwice: false -tracksRegLiveness: true -liveins: - - { reg: '%x0' } - - { reg: '%w1' } -frameInfo: - isFrameAddressTaken: false - isReturnAddressTaken: false - hasStackMap: false - hasPatchPoint: false - stackSize: 0 - offsetAdjustment: 0 - maxAlignment: 0 - adjustsStack: false - hasCalls: false - maxCallFrameSize: 0 - hasOpaqueSPAdjustment: false - hasVAStart: false - hasMustTailInVarArgFunc: false -body: | - bb.0 (%ir-block.0): - liveins: %w1, %x0, %lr - - STRWui %w1, %x0, 0 :: (store 4 into %ir.dst01) - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - CFI_INSTRUCTION 0 - STRWui killed %w1, killed %x0, 1 :: (store 4 into %ir.dst1) - RET %lr - -... -# CHECK-LABEL: name: store-pair -# CHECK: STPWi diff --git a/test/CodeGen/AArch64/ldst-opt.mir b/test/CodeGen/AArch64/ldst-opt.mir new file mode 100644 index 000000000000..8f0b71be3483 --- /dev/null +++ b/test/CodeGen/AArch64/ldst-opt.mir @@ -0,0 +1,132 @@ +# RUN: llc -mtriple=aarch64--linux-gnu -run-pass=aarch64-ldst-opt %s -verify-machineinstrs -o - 2>&1 | FileCheck %s +--- | + define void @promote-load-from-store() { ret void } + define void @store-pair() { ret void } + define void @store-pair-clearkill0() { ret void } + define void @store-pair-clearkill1() { ret void } +... +--- +name: promote-load-from-store +tracksRegLiveness: true +body: | + bb.0: + liveins: %w1, %x0, %lr + + STRWui killed %w1, %x0, 0 :: (store 4) + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + %w0 = LDRHHui killed %x0, 1 :: (load 2) + RET %lr, implicit %w0 + +... +# Don't count transient instructions towards search limits. +# CHECK-LABEL: name: promote-load-from-store +# CHECK: STRWui %w1 +# CHECK: UBFMWri %w1 +--- +name: store-pair +tracksRegLiveness: true +body: | + bb.0: + liveins: %w1, %x0, %lr + + STRWui %w1, %x0, 0 :: (store 4) + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + CFI_INSTRUCTION 0 + STRWui killed %w1, killed %x0, 1 :: (store 4) + RET %lr + +... +# CHECK-LABEL: name: store-pair +# CHECK: STPWi +--- +name: store-pair-clearkill0 +tracksRegLiveness: true +body: | + bb.0: + liveins: %w1, %x0, %lr + + STRWui %w1, %x0, 0 :: (store 4) + %w2 = COPY %w1 + %x3 = COPY %x0 + STRWui killed %w1, killed %x0, 1 :: (store 4) + RET %lr +... +# When merging a lower store with an upper one, we must clear kill flags on +# the lower store. +# CHECK-LABEL: store-pair-clearkill0 +# CHECK-NOT: STPWi %w1, killed %w1, %x0, 0 :: (store 4) +# CHECK: STPWi %w1, %w1, %x0, 0 :: (store 4) +# CHECK: %w2 = COPY %w1 +# CHECK: RET %lr +--- +name: store-pair-clearkill1 +tracksRegLiveness: true +body: | + bb.0: + liveins: %x0, %lr + + %w1 = MOVi32imm 13 + %w2 = MOVi32imm 7 + STRWui %w1, %x0, 1 :: (store 4) + %w2 = COPY killed %w1 + STRWui killed %w2, %x0, 0 :: (store 4) + + %w1 = MOVi32imm 42 + %w2 = MOVi32imm 7 + STRWui %w1, %x0, 0 :: (store 4) + %w2 = COPY killed %w1 + STRWui killed %w2, killed %x0, 1 :: (store 4) + + RET %lr +... +# When merging an upper store with a lower one, kill flags along the way need +# to be removed; In this case the kill flag on %w1. +# CHECK-LABEL: store-pair-clearkill1 +# CHECK: %w1 = MOVi32imm +# CHECK: %w2 = MOVi32imm +# CHECK-NOT: %w2 = COPY killed %w1 +# CHECK: %w2 = COPY %w1 +# CHECK: STPWi killed %w2, %w1, %x0, 0 + +# CHECK: %w1 = MOVi32imm +# CHECK: %w2 = MOVi32imm +# CHECK-NOT: %w2 = COPY killed %w1 +# CHECK: %w2 = COPY %w1 +# CHECK: STPWi %w1, killed %w2, killed %x0, 0 diff --git a/test/CodeGen/Thumb2/float-intrinsics-double.ll b/test/CodeGen/Thumb2/float-intrinsics-double.ll index 9e9499083829..657d1b172da9 100644 --- a/test/CodeGen/Thumb2/float-intrinsics-double.ll +++ b/test/CodeGen/Thumb2/float-intrinsics-double.ll @@ -18,7 +18,7 @@ declare double @llvm.powi.f64(double %Val, i32 %power) define double @powi_d(double %a, i32 %b) { ; CHECK-LABEL: powi_d: ; SOFT: {{(bl|b)}} __powidf2 -; HARD: bl __powidf2 +; HARD: b __powidf2 %1 = call double @llvm.powi.f64(double %a, i32 %b) ret double %1 } diff --git a/test/CodeGen/Thumb2/float-intrinsics-float.ll b/test/CodeGen/Thumb2/float-intrinsics-float.ll index fda840d90f36..847aeacd2f91 100644 --- a/test/CodeGen/Thumb2/float-intrinsics-float.ll +++ b/test/CodeGen/Thumb2/float-intrinsics-float.ll @@ -18,7 +18,7 @@ declare float @llvm.powi.f32(float %Val, i32 %power) define float @powi_f(float %a, i32 %b) { ; CHECK-LABEL: powi_f: ; SOFT: bl __powisf2 -; HARD: bl __powisf2 +; HARD: b __powisf2 %1 = call float @llvm.powi.f32(float %a, i32 %b) ret float %1 } diff --git a/test/CodeGen/Thumb2/intrinsics-cc.ll b/test/CodeGen/Thumb2/intrinsics-cc.ll new file mode 100644 index 000000000000..ab5081e3ab92 --- /dev/null +++ b/test/CodeGen/Thumb2/intrinsics-cc.ll @@ -0,0 +1,41 @@ +; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH +; RUN: llc -mtriple thumbv7-unknown-none-eabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT +; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD +; RUN: llc -mtriple thumbv7-unknown-none-eabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH + +; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH +; RUN: llc -mtriple thumbv7-unknown-none-gnueabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT +; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD +; RUN: llc -mtriple thumbv7-unknown-none-gnueabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH + +; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH +; RUN: llc -mtriple thumbv7-unknown-none-musleabi -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-SOFT +; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi soft -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MISMATCH -check-prefix CHECK-TO-HARD +; RUN: llc -mtriple thumbv7-unknown-none-musleabihf -float-abi hard -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-MATCH + +declare float @llvm.powi.f32(float, i32) + +define float @f(float %f, i32 %i) { +entry: + %0 = call float @llvm.powi.f32(float %f, i32 %i) + ret float %0 +} + +; CHECK-MATCH: b __powisf2 +; CHECK-MISMATCH: bl __powisf2 +; CHECK-TO-SOFT: vmov s0, r0 +; CHECK-TO-HARD: vmov r0, s0 + +declare double @llvm.powi.f64(double, i32) + +define double @g(double %d, i32 %i) { +entry: + %0 = call double @llvm.powi.f64(double %d, i32 %i) + ret double %0 +} + +; CHECK-MATCH: b __powidf2 +; CHECK-MISMATCH: bl __powidf2 +; CHECK-TO-SOFT: vmov d0, r0, r1 +; CHECK-TO-HARD: vmov r0, r1, d0 + diff --git a/test/CodeGen/X86/sse1.ll b/test/CodeGen/X86/sse1.ll index beedb1d24655..9488d6d26056 100644 --- a/test/CodeGen/X86/sse1.ll +++ b/test/CodeGen/X86/sse1.ll @@ -215,3 +215,136 @@ define <4 x i32> @PR30512(<4 x i32> %x, <4 x i32> %y) nounwind { ret <4 x i32> %zext } +; Fragile test warning - we need to induce the generation of a vselect +; post-legalization to cause the crash seen in: +; https://llvm.org/bugs/show_bug.cgi?id=31672 +; Is there a way to do that without an unsafe/fast sqrt intrinsic call? +; Also, although the goal for adding this test is to prove that we +; don't crash, I have no idea what this code is doing, so I'm keeping +; the full codegen checks in case there's motivation to improve this. + +define <2 x float> @PR31672() #0 { +; X32-LABEL: PR31672: +; X32: # BB#0: +; X32-NEXT: pushl %ebp +; X32-NEXT: movl %esp, %ebp +; X32-NEXT: andl $-16, %esp +; X32-NEXT: subl $80, %esp +; X32-NEXT: xorps %xmm0, %xmm0 +; X32-NEXT: movaps {{.*#+}} xmm1 = <42,3,u,u> +; X32-NEXT: movaps %xmm1, %xmm2 +; X32-NEXT: cmpeqps %xmm0, %xmm2 +; X32-NEXT: movaps %xmm2, {{[0-9]+}}(%esp) +; X32-NEXT: movaps %xmm0, {{[0-9]+}}(%esp) +; X32-NEXT: rsqrtps %xmm1, %xmm0 +; X32-NEXT: mulps %xmm0, %xmm1 +; X32-NEXT: mulps %xmm0, %xmm1 +; X32-NEXT: addps {{\.LCPI.*}}, %xmm1 +; X32-NEXT: mulps {{\.LCPI.*}}, %xmm0 +; X32-NEXT: mulps %xmm1, %xmm0 +; X32-NEXT: movaps %xmm0, {{[0-9]+}}(%esp) +; X32-NEXT: movl {{[0-9]+}}(%esp), %eax +; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: andl %eax, %ecx +; X32-NEXT: notl %eax +; X32-NEXT: andl {{[0-9]+}}(%esp), %eax +; X32-NEXT: orl %ecx, %eax +; X32-NEXT: movl %eax, (%esp) +; X32-NEXT: movl {{[0-9]+}}(%esp), %eax +; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: movl {{[0-9]+}}(%esp), %edx +; X32-NEXT: andl %ecx, %edx +; X32-NEXT: notl %ecx +; X32-NEXT: andl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: orl %edx, %ecx +; X32-NEXT: movl %ecx, {{[0-9]+}}(%esp) +; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: movl {{[0-9]+}}(%esp), %edx +; X32-NEXT: andl %ecx, %edx +; X32-NEXT: notl %ecx +; X32-NEXT: andl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: orl %edx, %ecx +; X32-NEXT: movl %ecx, {{[0-9]+}}(%esp) +; X32-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X32-NEXT: andl %eax, %ecx +; X32-NEXT: notl %eax +; X32-NEXT: andl {{[0-9]+}}(%esp), %eax +; X32-NEXT: orl %ecx, %eax +; X32-NEXT: movl %eax, {{[0-9]+}}(%esp) +; X32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X32-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero +; X32-NEXT: unpcklps {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1] +; X32-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero +; X32-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X32-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] +; X32-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] +; X32-NEXT: movl %ebp, %esp +; X32-NEXT: popl %ebp +; X32-NEXT: retl +; +; X64-LABEL: PR31672: +; X64: # BB#0: +; X64-NEXT: xorps %xmm0, %xmm0 +; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) +; X64-NEXT: movaps {{.*#+}} xmm1 = <42,3,u,u> +; X64-NEXT: cmpeqps %xmm1, %xmm0 +; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) +; X64-NEXT: rsqrtps %xmm1, %xmm0 +; X64-NEXT: mulps %xmm0, %xmm1 +; X64-NEXT: mulps %xmm0, %xmm1 +; X64-NEXT: addps {{.*}}(%rip), %xmm1 +; X64-NEXT: mulps {{.*}}(%rip), %xmm0 +; X64-NEXT: mulps %xmm1, %xmm0 +; X64-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp) +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r8 +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r9 +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %r10 +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdi +; X64-NEXT: movl %r9d, %esi +; X64-NEXT: andl %edi, %esi +; X64-NEXT: movl %edi, %ecx +; X64-NEXT: notl %ecx +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rdx +; X64-NEXT: movq -{{[0-9]+}}(%rsp), %rax +; X64-NEXT: andl %eax, %ecx +; X64-NEXT: orl %esi, %ecx +; X64-NEXT: movl %ecx, -{{[0-9]+}}(%rsp) +; X64-NEXT: movl %r8d, %ecx +; X64-NEXT: andl %r10d, %ecx +; X64-NEXT: movl %r10d, %esi +; X64-NEXT: notl %esi +; X64-NEXT: andl %edx, %esi +; X64-NEXT: orl %ecx, %esi +; X64-NEXT: movl %esi, -{{[0-9]+}}(%rsp) +; X64-NEXT: shrq $32, %r9 +; X64-NEXT: shrq $32, %rdi +; X64-NEXT: andl %edi, %r9d +; X64-NEXT: notl %edi +; X64-NEXT: shrq $32, %rax +; X64-NEXT: andl %edi, %eax +; X64-NEXT: orl %r9d, %eax +; X64-NEXT: movl %eax, -{{[0-9]+}}(%rsp) +; X64-NEXT: shrq $32, %r8 +; X64-NEXT: shrq $32, %r10 +; X64-NEXT: andl %r10d, %r8d +; X64-NEXT: notl %r10d +; X64-NEXT: shrq $32, %rdx +; X64-NEXT: andl %r10d, %edx +; X64-NEXT: orl %r8d, %edx +; X64-NEXT: movl %edx, -{{[0-9]+}}(%rsp) +; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero +; X64-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero +; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1] +; X64-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero +; X64-NEXT: movss {{.*#+}} xmm2 = mem[0],zero,zero,zero +; X64-NEXT: unpcklps {{.*#+}} xmm2 = xmm2[0],xmm1[0],xmm2[1],xmm1[1] +; X64-NEXT: unpcklps {{.*#+}} xmm0 = xmm0[0],xmm2[0],xmm0[1],xmm2[1] +; X64-NEXT: retq + %t0 = call fast <2 x float> @llvm.sqrt.v2f32(<2 x float> <float 42.0, float 3.0>) + ret <2 x float> %t0 +} + +declare <2 x float> @llvm.sqrt.v2f32(<2 x float>) #1 + +attributes #0 = { nounwind "unsafe-fp-math"="true" } + |
