[clang] [compiler-rt] [llvm] [TargetLowering] Set the default `getCmpLibcallReturnType` to word size (PR #192441)

Trevor Gross via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 01:22:48 PDT 2026


https://github.com/tgross35 updated https://github.com/llvm/llvm-project/pull/192441

>From 385a4b1e0b214bb771faa3cda7bbe255dd32cbf9 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Thu, 16 Apr 2026 04:33:09 -0400
Subject: [PATCH 1/6] [WebAssembly] Explicitly set `getCmpLibcallReturnType` to
 i32

LLVM's default for `getCmpLibcallReturnType` is currently set to `i32`,
but this is not exactly accurate: the default in GCC is an integer of
word size. This means that on wasm64 targets, runtime libraries that are
assuming word size are incorrect and instead need to be using a 32-bit
integer.

The unintentional i32 default is actually a reasonable choice for Wasm
because it may be slightly cheaper to operate on when running 64-bit
wasm on 32-bit hosts, and there is no advantage to using a larger
integer (the result of comparisons need only be able to represent three
possible values). Thus, make the `i32` explicit.

GCC does not support wasm64 so there is no compatibility concern at the
current time. If added, it would be reasonable for `i32` to be used
there as well.
---
 llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
index 42f047840e504..f3ecd520a6076 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -29,6 +29,11 @@ class WebAssemblyTargetLowering final : public TargetLowering {
   MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override;
   MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override;
 
+  MVT::SimpleValueType getCmpLibcallReturnType() const override {
+    // i32 may be more efficient than the default word size for wasm64 targets
+    return MVT::i32;
+  }
+
 private:
   /// Keep a pointer to the WebAssemblySubtarget around so that we can make the
   /// right decision when generating code for different targets.

>From 1fae1b365a99fc1caba01702dc171c6fa404489e Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Mon, 27 Apr 2026 01:54:25 -0400
Subject: [PATCH 2/6] [X86] Explicitly set `getCmpLibcallReturnType` to i32

LLVM's default for `getCmpLibcallReturnType` will be changing from an
`i32` to word size. On x86-64, the encoding for `test` and `cmp`
operations is two bytes for 32-bit operands but three bytes for 64-bit
operands. There is no advantage to using the 64-bit versions here, so
override to `i32` to keep saving the extra byte.

Note that GCC does not yet match this behavior [1].

[1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125034
---
 compiler-rt/lib/builtins/fp_compare_impl.inc | 5 +++++
 llvm/lib/Target/X86/X86ISelLowering.h        | 5 +++++
 2 files changed, 10 insertions(+)

diff --git a/compiler-rt/lib/builtins/fp_compare_impl.inc b/compiler-rt/lib/builtins/fp_compare_impl.inc
index 129d0136a0b98..0fa9faf7c2730 100644
--- a/compiler-rt/lib/builtins/fp_compare_impl.inc
+++ b/compiler-rt/lib/builtins/fp_compare_impl.inc
@@ -15,6 +15,11 @@
 #if defined(__aarch64__) || defined(__arm64ec__)
 // AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
 typedef int CMP_RESULT;
+#elif defined(__i386__) || defined(__x86_64__)
+// x86 targets always use an i32 for smaller encoding. Note that as of 2026-04
+// this does not match libgcc, but the needed comparisons to 0 are compatible
+// across sizes.
+typedef int CMP_RESULT;
 #elif defined(__wasm__)
 // Both wasm32 and wasm64 use i32
 typedef int CMP_RESULT;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index 5c7c54cacd239..be58c9f72fb99 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -323,6 +323,11 @@ namespace llvm {
     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
                            EVT VT) const override;
 
+    MVT::SimpleValueType getCmpLibcallReturnType() const override {
+      // 32-bit comparisons have a smaller encoding than 64-bit on x86-64.
+      return MVT::i32;
+    }
+
     bool targetShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
                                       const APInt &DemandedElts,
                                       TargetLoweringOpt &TLO) const override;

>From 1f9951a360024aada25fa9cf16722f82c2e7d842 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Sun, 26 Apr 2026 04:09:29 -0400
Subject: [PATCH 3/6] update docs, address 16-bit targets

---
 compiler-rt/lib/builtins/fp_compare_impl.inc | 18 +++++++++++++-----
 compiler-rt/lib/builtins/int_types.h         |  7 -------
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/compiler-rt/lib/builtins/fp_compare_impl.inc b/compiler-rt/lib/builtins/fp_compare_impl.inc
index adac5650cf601..719adf7f43b08 100644
--- a/compiler-rt/lib/builtins/fp_compare_impl.inc
+++ b/compiler-rt/lib/builtins/fp_compare_impl.inc
@@ -8,10 +8,10 @@
 
 #include "fp_lib.h"
 
-// GCC defaults to a word-sized return value, with a few platforms hooking
-// the override. We need to ensure that the return value is sign-extended in
-// the same way as GCC expects (since otherwise GCC-generated __builtin_isinf
-// returns true for finite 128-bit floating-point numbers).
+// GCC defaults to a word-sized (register-sized) return value, with a few
+// platforms hooking the override. If the type defined here is not ABI-
+// compatible with `getCmpLibcallReturnType`, comparison results will be
+// invalid.
 #if defined(__aarch64__) || defined(__arm64ec__)
 // AArch64 GCC overrides libgcc_cmp_return to use an int.
 typedef int CMP_RESULT;
@@ -28,7 +28,15 @@ typedef int CMP_RESULT;
 typedef char CMP_RESULT;
 #else
 // By default, use a signed word.
-typedef sword CMP_RESULT;
+#if __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
+// LLP64 ABIs need to use `long long` for word size.
+typedef long long CMP_RESULT;
+#elif __SIZEOF_POINTER__ == 2
+// `long` is four bytes on IP16L32 ABIs so `int` must be used.
+typedef int CMP_RESULT
+#else
+typedef long CMP_RESULT;
+#endif
 #endif
 
 #if !defined(__clang__) && defined(__GNUC__)
diff --git a/compiler-rt/lib/builtins/int_types.h b/compiler-rt/lib/builtins/int_types.h
index ea58c36c957b3..6411507efdc87 100644
--- a/compiler-rt/lib/builtins/int_types.h
+++ b/compiler-rt/lib/builtins/int_types.h
@@ -18,13 +18,6 @@
 
 #include "int_endianness.h"
 
-#if __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
-// LLP64 ABIs use long long instead of long.
-typedef long long sword;
-#else
-typedef long sword;
-#endif
-
 // si_int is defined in Linux sysroot's asm-generic/siginfo.h
 #ifdef si_int
 #undef si_int

>From 775c5ab57aaf48eefc950c6793479acda13565c9 Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Sun, 26 Apr 2026 17:17:49 -0400
Subject: [PATCH 4/6] Switch to getRegisterWidth

---
 clang/include/clang/Basic/TargetInfo.h     | 1 +
 llvm/include/llvm/CodeGen/TargetLowering.h | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 9f7d2a17a0f8a..aaea1205cca80 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -908,6 +908,7 @@ class TargetInfo : public TransferrableTargetInfo,
     // Currently we assume the register width on the target matches the pointer
     // width, we can introduce a new variable for this if/when some target wants
     // it.
+    // NOTE: This should match LLVM's `getRegisterWidth`.
     return PointerWidth;
   }
 
diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 2782bd4d04b51..35bc56b22e804 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -993,6 +993,13 @@ class LLVM_ABI TargetLoweringBase {
   virtual EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
                                  EVT VT) const;
 
+  /// Return the "preferred" register width on this target.
+  virtual unsigned getRegisterWidth(const DataLayout &DL) const {
+    // Currently we assume the register width matches the pointer width.
+    // NOTE: This should match Clang's `getRegisterWidth`.
+    return DL.getAddressSizeInBits(0u);
+  }
+
   /// Return the ValueType for comparison libcalls. Comparison libcalls include
   /// floating point comparison calls, and Ordered/Unordered check calls on
   /// floating point numbers.
@@ -1002,7 +1009,7 @@ class LLVM_ABI TargetLoweringBase {
   /// targets that have a cheaper comparison at other sizes.
   virtual MVT::SimpleValueType
   getCmpLibcallReturnType(const DataLayout &DL) const {
-    return getPointerTy(DL).SimpleTy;
+    return MVT::getIntegerVT(getRegisterWidth(DL)).SimpleTy;
   }
 
   /// For targets without i1 registers, this gives the nature of the high-bits

>From 5cde4e5e7f1048e7bba9b971e88b7bb83f55cc2f Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Mon, 27 Apr 2026 01:54:25 -0400
Subject: [PATCH 5/6] restore x86 tests, update comment

---
 llvm/include/llvm/CodeGen/TargetLowering.h    |  3 +-
 llvm/lib/Target/X86/X86ISelLowering.h         |  3 +-
 .../CodeGen/X86/fminimumnum-fmaximumnum.ll    | 48 +++++++++----------
 llvm/test/CodeGen/X86/fp128-cast.ll           |  8 ++--
 llvm/test/CodeGen/X86/fp128-compare.ll        | 22 ++++-----
 llvm/test/CodeGen/X86/fp128-i128.ll           | 20 ++++----
 .../test/CodeGen/X86/fp128-libcalls-strict.ll | 36 +++++++-------
 llvm/test/CodeGen/X86/fp128-select.ll         | 18 +++----
 .../CodeGen/X86/soft-fp-legal-in-HW-reg.ll    |  4 +-
 9 files changed, 82 insertions(+), 80 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 35bc56b22e804..5ea97b41922d4 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -1006,7 +1006,8 @@ class LLVM_ABI TargetLoweringBase {
   ///
   /// This should match `CMP_RESULT` in `compiler-rt` and `CMPtype` in
   /// `libgcc`. The default return is word-sized. Consider overriding on
-  /// targets that have a cheaper comparison at other sizes.
+  /// targets that have a cheaper comparison or smaller comparison
+  /// encoding at other sizes.
   virtual MVT::SimpleValueType
   getCmpLibcallReturnType(const DataLayout &DL) const {
     return MVT::getIntegerVT(getRegisterWidth(DL)).SimpleTy;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index be58c9f72fb99..53c62741f89ce 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -323,7 +323,8 @@ namespace llvm {
     EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
                            EVT VT) const override;
 
-    MVT::SimpleValueType getCmpLibcallReturnType() const override {
+    MVT::SimpleValueType
+    getCmpLibcallReturnType(const DataLayout &DL) const override {
       // 32-bit comparisons have a smaller encoding than 64-bit on x86-64.
       return MVT::i32;
     }
diff --git a/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll b/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
index d2a75abf1bc42..8abd68701676c 100644
--- a/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
+++ b/llvm/test/CodeGen/X86/fminimumnum-fmaximumnum.ll
@@ -3170,7 +3170,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    callq __unordtf2 at PLT
 ; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    jne .LBB41_2
 ; SSE2-NEXT:  # %bb.1: # %start
@@ -3179,7 +3179,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    callq __unordtf2 at PLT
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; SSE2-NEXT:    jne .LBB41_4
 ; SSE2-NEXT:  # %bb.3: # %start
@@ -3189,7 +3189,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
 ; SSE2-NEXT:    callq __gttf2 at PLT
 ; SSE2-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
 ; SSE2-NEXT:    jg .LBB41_6
 ; SSE2-NEXT:  # %bb.5: # %start
@@ -3207,7 +3207,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    pxor %xmm1, %xmm1
 ; SSE2-NEXT:    movaps %xmm2, %xmm0
 ; SSE2-NEXT:    callq __eqtf2 at PLT
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; SSE2-NEXT:    je .LBB41_10
 ; SSE2-NEXT:  # %bb.9: # %start
@@ -3224,7 +3224,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    callq __unordtf2 at PLT
 ; AVX-NEXT:    vmovaps (%rsp), %xmm0 # 16-byte Reload
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    jne .LBB41_2
 ; AVX-NEXT:  # %bb.1: # %start
@@ -3233,7 +3233,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    callq __unordtf2 at PLT
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; AVX-NEXT:    jne .LBB41_4
 ; AVX-NEXT:  # %bb.3: # %start
@@ -3243,7 +3243,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm1, (%rsp) # 16-byte Spill
 ; AVX-NEXT:    callq __gttf2 at PLT
 ; AVX-NEXT:    vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovdqa %xmm0, %xmm1
 ; AVX-NEXT:    jg .LBB41_6
 ; AVX-NEXT:  # %bb.5: # %start
@@ -3261,7 +3261,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX-NEXT:    vmovaps %xmm2, %xmm0
 ; AVX-NEXT:    callq __eqtf2 at PLT
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; AVX-NEXT:    je .LBB41_10
 ; AVX-NEXT:  # %bb.9: # %start
@@ -3278,7 +3278,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    callq __unordtf2 at PLT
 ; AVX10_2-NEXT:    vmovaps (%rsp), %xmm0 # 16-byte Reload
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    jne .LBB41_2
 ; AVX10_2-NEXT:  # %bb.1: # %start
@@ -3287,7 +3287,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    callq __unordtf2 at PLT
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; AVX10_2-NEXT:    jne .LBB41_4
 ; AVX10_2-NEXT:  # %bb.3: # %start
@@ -3297,7 +3297,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm1, (%rsp) # 16-byte Spill
 ; AVX10_2-NEXT:    callq __gttf2 at PLT
 ; AVX10_2-NEXT:    vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovdqa %xmm0, %xmm1
 ; AVX10_2-NEXT:    jg .LBB41_6
 ; AVX10_2-NEXT:  # %bb.5: # %start
@@ -3315,7 +3315,7 @@ define fp128 @test_fmaximumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX10_2-NEXT:    vmovaps %xmm2, %xmm0
 ; AVX10_2-NEXT:    callq __eqtf2 at PLT
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; AVX10_2-NEXT:    je .LBB41_10
 ; AVX10_2-NEXT:  # %bb.9: # %start
@@ -3360,7 +3360,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    callq __unordtf2 at PLT
 ; SSE2-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    jne .LBB42_2
 ; SSE2-NEXT:  # %bb.1: # %start
@@ -3369,7 +3369,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE2-NEXT:    movaps %xmm0, %xmm1
 ; SSE2-NEXT:    callq __unordtf2 at PLT
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; SSE2-NEXT:    jne .LBB42_4
 ; SSE2-NEXT:  # %bb.3: # %start
@@ -3379,7 +3379,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
 ; SSE2-NEXT:    callq __lttf2 at PLT
 ; SSE2-NEXT:    movdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movdqa %xmm0, %xmm1
 ; SSE2-NEXT:    js .LBB42_6
 ; SSE2-NEXT:  # %bb.5: # %start
@@ -3397,7 +3397,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; SSE2-NEXT:    pxor %xmm1, %xmm1
 ; SSE2-NEXT:    movaps %xmm2, %xmm0
 ; SSE2-NEXT:    callq __eqtf2 at PLT
-; SSE2-NEXT:    testq %rax, %rax
+; SSE2-NEXT:    testl %eax, %eax
 ; SSE2-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; SSE2-NEXT:    je .LBB42_10
 ; SSE2-NEXT:  # %bb.9: # %start
@@ -3414,7 +3414,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    callq __unordtf2 at PLT
 ; AVX-NEXT:    vmovaps (%rsp), %xmm0 # 16-byte Reload
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    jne .LBB42_2
 ; AVX-NEXT:  # %bb.1: # %start
@@ -3423,7 +3423,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    callq __unordtf2 at PLT
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; AVX-NEXT:    jne .LBB42_4
 ; AVX-NEXT:  # %bb.3: # %start
@@ -3433,7 +3433,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vmovaps %xmm1, (%rsp) # 16-byte Spill
 ; AVX-NEXT:    callq __lttf2 at PLT
 ; AVX-NEXT:    vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovdqa %xmm0, %xmm1
 ; AVX-NEXT:    js .LBB42_6
 ; AVX-NEXT:  # %bb.5: # %start
@@ -3451,7 +3451,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX-NEXT:    vmovaps %xmm2, %xmm0
 ; AVX-NEXT:    callq __eqtf2 at PLT
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; AVX-NEXT:    je .LBB42_10
 ; AVX-NEXT:  # %bb.9: # %start
@@ -3468,7 +3468,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    callq __unordtf2 at PLT
 ; AVX10_2-NEXT:    vmovaps (%rsp), %xmm0 # 16-byte Reload
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    jne .LBB42_2
 ; AVX10_2-NEXT:  # %bb.1: # %start
@@ -3477,7 +3477,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; AVX10_2-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX10_2-NEXT:    callq __unordtf2 at PLT
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; AVX10_2-NEXT:    jne .LBB42_4
 ; AVX10_2-NEXT:  # %bb.3: # %start
@@ -3487,7 +3487,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vmovaps %xmm1, (%rsp) # 16-byte Spill
 ; AVX10_2-NEXT:    callq __lttf2 at PLT
 ; AVX10_2-NEXT:    vmovdqa {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovdqa %xmm0, %xmm1
 ; AVX10_2-NEXT:    js .LBB42_6
 ; AVX10_2-NEXT:  # %bb.5: # %start
@@ -3505,7 +3505,7 @@ define fp128 @test_fminimumnum_fp128(fp128 %x, fp128 %y) nounwind {
 ; AVX10_2-NEXT:    vpxor %xmm1, %xmm1, %xmm1
 ; AVX10_2-NEXT:    vmovaps %xmm2, %xmm0
 ; AVX10_2-NEXT:    callq __eqtf2 at PLT
-; AVX10_2-NEXT:    testq %rax, %rax
+; AVX10_2-NEXT:    testl %eax, %eax
 ; AVX10_2-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; AVX10_2-NEXT:    je .LBB42_10
 ; AVX10_2-NEXT:  # %bb.9: # %start
diff --git a/llvm/test/CodeGen/X86/fp128-cast.ll b/llvm/test/CodeGen/X86/fp128-cast.ll
index e5631ba6dfcf6..6d4ec063ccd46 100644
--- a/llvm/test/CodeGen/X86/fp128-cast.ll
+++ b/llvm/test/CodeGen/X86/fp128-cast.ll
@@ -1024,7 +1024,7 @@ define dso_local i32 @TestConst128(fp128 %v) nounwind {
 ; X64-SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.0E+0]
 ; X64-SSE-NEXT:    callq __gttf2 at PLT
 ; X64-SSE-NEXT:    xorl %ecx, %ecx
-; X64-SSE-NEXT:    testq %rax, %rax
+; X64-SSE-NEXT:    testl %eax, %eax
 ; X64-SSE-NEXT:    setg %cl
 ; X64-SSE-NEXT:    movl %ecx, %eax
 ; X64-SSE-NEXT:    popq %rcx
@@ -1056,7 +1056,7 @@ define dso_local i32 @TestConst128(fp128 %v) nounwind {
 ; X64-AVX-NEXT:    vmovaps {{.*#+}} xmm1 = [1.0E+0]
 ; X64-AVX-NEXT:    callq __gttf2 at PLT
 ; X64-AVX-NEXT:    xorl %ecx, %ecx
-; X64-AVX-NEXT:    testq %rax, %rax
+; X64-AVX-NEXT:    testl %eax, %eax
 ; X64-AVX-NEXT:    setg %cl
 ; X64-AVX-NEXT:    movl %ecx, %eax
 ; X64-AVX-NEXT:    popq %rcx
@@ -1075,7 +1075,7 @@ define dso_local i32 @TestConst128Zero(fp128 %v) nounwind {
 ; X64-SSE-NEXT:    xorps %xmm1, %xmm1
 ; X64-SSE-NEXT:    callq __gttf2 at PLT
 ; X64-SSE-NEXT:    xorl %ecx, %ecx
-; X64-SSE-NEXT:    testq %rax, %rax
+; X64-SSE-NEXT:    testl %eax, %eax
 ; X64-SSE-NEXT:    setg %cl
 ; X64-SSE-NEXT:    movl %ecx, %eax
 ; X64-SSE-NEXT:    popq %rcx
@@ -1107,7 +1107,7 @@ define dso_local i32 @TestConst128Zero(fp128 %v) nounwind {
 ; X64-AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1
 ; X64-AVX-NEXT:    callq __gttf2 at PLT
 ; X64-AVX-NEXT:    xorl %ecx, %ecx
-; X64-AVX-NEXT:    testq %rax, %rax
+; X64-AVX-NEXT:    testl %eax, %eax
 ; X64-AVX-NEXT:    setg %cl
 ; X64-AVX-NEXT:    movl %ecx, %eax
 ; X64-AVX-NEXT:    popq %rcx
diff --git a/llvm/test/CodeGen/X86/fp128-compare.ll b/llvm/test/CodeGen/X86/fp128-compare.ll
index 97c1f5008e4dd..3851e59a08e35 100644
--- a/llvm/test/CodeGen/X86/fp128-compare.ll
+++ b/llvm/test/CodeGen/X86/fp128-compare.ll
@@ -11,7 +11,7 @@ define i32 @TestComp128GT(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __gttf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setg %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -30,7 +30,7 @@ define i32 @TestComp128GE(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __getf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setns %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -49,7 +49,7 @@ define i32 @TestComp128LT(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __lttf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    sets %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -71,7 +71,7 @@ define i32 @TestComp128LE(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __letf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setle %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -90,7 +90,7 @@ define i32 @TestComp128EQ(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __eqtf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    sete %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -109,7 +109,7 @@ define i32 @TestComp128NE(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    .cfi_def_cfa_offset 16
 ; CHECK-NEXT:    callq __netf2 at PLT
 ; CHECK-NEXT:    xorl %ecx, %ecx
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setne %cl
 ; CHECK-NEXT:    movl %ecx, %eax
 ; CHECK-NEXT:    popq %rcx
@@ -132,12 +132,12 @@ define i32 @TestComp128UEQ(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
 ; CHECK-NEXT:    callq __eqtf2 at PLT
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    sete %bl
 ; CHECK-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; CHECK-NEXT:    callq __unordtf2 at PLT
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setne %al
 ; CHECK-NEXT:    orb %bl, %al
 ; CHECK-NEXT:    movzbl %al, %eax
@@ -163,12 +163,12 @@ define i32 @TestComp128ONE(fp128 %d1, fp128 %d2) {
 ; CHECK-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
 ; CHECK-NEXT:    callq __eqtf2 at PLT
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    setne %bl
 ; CHECK-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; CHECK-NEXT:    callq __unordtf2 at PLT
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    sete %al
 ; CHECK-NEXT:    andb %bl, %al
 ; CHECK-NEXT:    movzbl %al, %eax
@@ -192,7 +192,7 @@ define fp128 @TestMax(fp128 %x, fp128 %y) {
 ; CHECK-NEXT:    movaps %xmm1, (%rsp) # 16-byte Spill
 ; CHECK-NEXT:    callq __gttf2 at PLT
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
-; CHECK-NEXT:    testq %rax, %rax
+; CHECK-NEXT:    testl %eax, %eax
 ; CHECK-NEXT:    jg .LBB8_2
 ; CHECK-NEXT:  # %bb.1: # %entry
 ; CHECK-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
diff --git a/llvm/test/CodeGen/X86/fp128-i128.ll b/llvm/test/CodeGen/X86/fp128-i128.ll
index 15bf183d9a90d..338950ac4c350 100644
--- a/llvm/test/CodeGen/X86/fp128-i128.ll
+++ b/llvm/test/CodeGen/X86/fp128-i128.ll
@@ -135,7 +135,7 @@ define fp128 @TestI128_1(fp128 %x) #0 {
 ; SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.00000000000000000000000000000000005E-1]
 ; SSE-NEXT:    callq __lttf2 at PLT
 ; SSE-NEXT:    xorl %ecx, %ecx
-; SSE-NEXT:    testq %rax, %rax
+; SSE-NEXT:    testl %eax, %eax
 ; SSE-NEXT:    sets %cl
 ; SSE-NEXT:    shll $4, %ecx
 ; SSE-NEXT:    movaps {{.*#+}} xmm0 = [?]
@@ -149,7 +149,7 @@ define fp128 @TestI128_1(fp128 %x) #0 {
 ; AVX-NEXT:    vmovaps {{.*#+}} xmm1 = [1.00000000000000000000000000000000005E-1]
 ; AVX-NEXT:    callq __lttf2 at PLT
 ; AVX-NEXT:    xorl %ecx, %ecx
-; AVX-NEXT:    testq %rax, %rax
+; AVX-NEXT:    testl %eax, %eax
 ; AVX-NEXT:    sets %cl
 ; AVX-NEXT:    shll $4, %ecx
 ; AVX-NEXT:    vmovaps {{.*#+}} xmm0 = [?]
@@ -431,7 +431,7 @@ declare fp128 @copysignl(fp128, fp128) #1
 define dso_local void @TestCopySign(ptr noalias nocapture sret({ fp128, fp128 }) %agg.result, ptr byval({ fp128, fp128 }) nocapture readonly align 16 %z) #0 {
 ; SSE-LABEL: TestCopySign:
 ; SSE:       # %bb.0: # %entry
-; SSE-NEXT:    pushq %r14
+; SSE-NEXT:    pushq %rbp
 ; SSE-NEXT:    pushq %rbx
 ; SSE-NEXT:    subq $40, %rsp
 ; SSE-NEXT:    movq %rdi, %rbx
@@ -440,11 +440,11 @@ define dso_local void @TestCopySign(ptr noalias nocapture sret({ fp128, fp128 })
 ; SSE-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    callq __gttf2 at PLT
-; SSE-NEXT:    movq %rax, %r14
+; SSE-NEXT:    movl %eax, %ebp
 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    movaps %xmm0, %xmm1
 ; SSE-NEXT:    callq __subtf3 at PLT
-; SSE-NEXT:    testq %r14, %r14
+; SSE-NEXT:    testl %ebp, %ebp
 ; SSE-NEXT:    jle .LBB10_1
 ; SSE-NEXT:  # %bb.2: # %if.then
 ; SSE-NEXT:    movaps %xmm0, %xmm1
@@ -463,12 +463,12 @@ define dso_local void @TestCopySign(ptr noalias nocapture sret({ fp128, fp128 })
 ; SSE-NEXT:    movq %rbx, %rax
 ; SSE-NEXT:    addq $40, %rsp
 ; SSE-NEXT:    popq %rbx
-; SSE-NEXT:    popq %r14
+; SSE-NEXT:    popq %rbp
 ; SSE-NEXT:    retq
 ;
 ; AVX-LABEL: TestCopySign:
 ; AVX:       # %bb.0: # %entry
-; AVX-NEXT:    pushq %r14
+; AVX-NEXT:    pushq %rbp
 ; AVX-NEXT:    pushq %rbx
 ; AVX-NEXT:    subq $40, %rsp
 ; AVX-NEXT:    movq %rdi, %rbx
@@ -477,11 +477,11 @@ define dso_local void @TestCopySign(ptr noalias nocapture sret({ fp128, fp128 })
 ; AVX-NEXT:    vmovaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; AVX-NEXT:    vmovaps %xmm0, (%rsp) # 16-byte Spill
 ; AVX-NEXT:    callq __gttf2 at PLT
-; AVX-NEXT:    movq %rax, %r14
+; AVX-NEXT:    movl %eax, %ebp
 ; AVX-NEXT:    vmovaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 16-byte Reload
 ; AVX-NEXT:    vmovaps %xmm0, %xmm1
 ; AVX-NEXT:    callq __subtf3 at PLT
-; AVX-NEXT:    testq %r14, %r14
+; AVX-NEXT:    testl %ebp, %ebp
 ; AVX-NEXT:    jle .LBB10_1
 ; AVX-NEXT:  # %bb.2: # %if.then
 ; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm2
@@ -499,7 +499,7 @@ define dso_local void @TestCopySign(ptr noalias nocapture sret({ fp128, fp128 })
 ; AVX-NEXT:    movq %rbx, %rax
 ; AVX-NEXT:    addq $40, %rsp
 ; AVX-NEXT:    popq %rbx
-; AVX-NEXT:    popq %r14
+; AVX-NEXT:    popq %rbp
 ; AVX-NEXT:    retq
 entry:
   %z.realp = getelementptr inbounds { fp128, fp128 }, ptr %z, i64 0, i32 0
diff --git a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
index 94a141d116193..ad2d690fd7ed0 100644
--- a/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
+++ b/llvm/test/CodeGen/X86/fp128-libcalls-strict.ll
@@ -3548,7 +3548,7 @@ define i64 @cmp(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; ANDROID-NEXT:    movq %rsi, %rbx
 ; ANDROID-NEXT:    movq %rdi, %r14
 ; ANDROID-NEXT:    callq __eqtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    cmovneq %rbx, %r14
 ; ANDROID-NEXT:    movq %r14, %rax
 ; ANDROID-NEXT:    addq $8, %rsp
@@ -3564,7 +3564,7 @@ define i64 @cmp(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; GNU-NEXT:    movq %rsi, %rbx
 ; GNU-NEXT:    movq %rdi, %r14
 ; GNU-NEXT:    callq __eqtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    cmovneq %rbx, %r14
 ; GNU-NEXT:    movq %r14, %rax
 ; GNU-NEXT:    addq $8, %rsp
@@ -3608,7 +3608,7 @@ define i64 @cmp(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    callq __eqtf2
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    cmovneq %rsi, %rdi
 ; WIN-NEXT:    movq %rdi, %rax
 ; WIN-NEXT:    addq $72, %rsp
@@ -3678,7 +3678,7 @@ define i64 @cmps(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; ANDROID-NEXT:    movq %rsi, %rbx
 ; ANDROID-NEXT:    movq %rdi, %r14
 ; ANDROID-NEXT:    callq __eqtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    cmovneq %rbx, %r14
 ; ANDROID-NEXT:    movq %r14, %rax
 ; ANDROID-NEXT:    addq $8, %rsp
@@ -3694,7 +3694,7 @@ define i64 @cmps(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; GNU-NEXT:    movq %rsi, %rbx
 ; GNU-NEXT:    movq %rdi, %r14
 ; GNU-NEXT:    callq __eqtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    cmovneq %rbx, %r14
 ; GNU-NEXT:    movq %r14, %rax
 ; GNU-NEXT:    addq $8, %rsp
@@ -3738,7 +3738,7 @@ define i64 @cmps(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    callq __eqtf2
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    cmovneq %rsi, %rdi
 ; WIN-NEXT:    movq %rdi, %rax
 ; WIN-NEXT:    addq $72, %rsp
@@ -3822,12 +3822,12 @@ define i64 @cmp_ueq_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; ANDROID-NEXT:    movq %rsi, %rbx
 ; ANDROID-NEXT:    movq %rdi, %r14
 ; ANDROID-NEXT:    callq __eqtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    sete %bpl
 ; ANDROID-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; ANDROID-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; ANDROID-NEXT:    callq __unordtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    setne %al
 ; ANDROID-NEXT:    orb %bpl, %al
 ; ANDROID-NEXT:    cmoveq %rbx, %r14
@@ -3849,12 +3849,12 @@ define i64 @cmp_ueq_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; GNU-NEXT:    movq %rsi, %rbx
 ; GNU-NEXT:    movq %rdi, %r14
 ; GNU-NEXT:    callq __eqtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    sete %bpl
 ; GNU-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; GNU-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; GNU-NEXT:    callq __unordtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    setne %al
 ; GNU-NEXT:    orb %bpl, %al
 ; GNU-NEXT:    cmoveq %rbx, %r14
@@ -3929,12 +3929,12 @@ define i64 @cmp_ueq_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; WIN-NEXT:    callq __eqtf2
 ; WIN-NEXT:    movaps %xmm7, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm6, {{[0-9]+}}(%rsp)
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    sete %bl
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    callq __unordtf2
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    setne %al
 ; WIN-NEXT:    orb %bl, %al
 ; WIN-NEXT:    cmoveq %rsi, %rdi
@@ -4043,12 +4043,12 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; ANDROID-NEXT:    movq %rsi, %rbx
 ; ANDROID-NEXT:    movq %rdi, %r14
 ; ANDROID-NEXT:    callq __eqtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    setne %bpl
 ; ANDROID-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; ANDROID-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; ANDROID-NEXT:    callq __unordtf2 at PLT
-; ANDROID-NEXT:    testq %rax, %rax
+; ANDROID-NEXT:    testl %eax, %eax
 ; ANDROID-NEXT:    sete %al
 ; ANDROID-NEXT:    testb %bpl, %al
 ; ANDROID-NEXT:    cmoveq %rbx, %r14
@@ -4070,12 +4070,12 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; GNU-NEXT:    movq %rsi, %rbx
 ; GNU-NEXT:    movq %rdi, %r14
 ; GNU-NEXT:    callq __eqtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    setne %bpl
 ; GNU-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; GNU-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; GNU-NEXT:    callq __unordtf2 at PLT
-; GNU-NEXT:    testq %rax, %rax
+; GNU-NEXT:    testl %eax, %eax
 ; GNU-NEXT:    sete %al
 ; GNU-NEXT:    testb %bpl, %al
 ; GNU-NEXT:    cmoveq %rbx, %r14
@@ -4152,12 +4152,12 @@ define i64 @cmp_one_q(i64 %a, i64 %b, fp128 %x, fp128 %y) #0 {
 ; WIN-NEXT:    callq __eqtf2
 ; WIN-NEXT:    movaps %xmm7, {{[0-9]+}}(%rsp)
 ; WIN-NEXT:    movaps %xmm6, {{[0-9]+}}(%rsp)
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    setne %bl
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rcx
 ; WIN-NEXT:    leaq {{[0-9]+}}(%rsp), %rdx
 ; WIN-NEXT:    callq __unordtf2
-; WIN-NEXT:    testq %rax, %rax
+; WIN-NEXT:    testl %eax, %eax
 ; WIN-NEXT:    sete %al
 ; WIN-NEXT:    testb %bl, %al
 ; WIN-NEXT:    cmoveq %rsi, %rdi
diff --git a/llvm/test/CodeGen/X86/fp128-select.ll b/llvm/test/CodeGen/X86/fp128-select.ll
index 880a3d6873822..27a651e23f886 100644
--- a/llvm/test/CodeGen/X86/fp128-select.ll
+++ b/llvm/test/CodeGen/X86/fp128-select.ll
@@ -48,11 +48,11 @@ define fp128 @test_select_cc(fp128, fp128) nounwind {
 ; SSE-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; SSE-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
 ; SSE-NEXT:    callq __netf2 at PLT
-; SSE-NEXT:    movq %rax, %rbx
+; SSE-NEXT:    movl %eax, %ebx
 ; SSE-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; SSE-NEXT:    callq __eqtf2 at PLT
-; SSE-NEXT:    testq %rax, %rax
+; SSE-NEXT:    testl %eax, %eax
 ; SSE-NEXT:    je .LBB1_1
 ; SSE-NEXT:  # %bb.2: # %BB0
 ; SSE-NEXT:    xorps %xmm1, %xmm1
@@ -60,7 +60,7 @@ define fp128 @test_select_cc(fp128, fp128) nounwind {
 ; SSE-NEXT:  .LBB1_1:
 ; SSE-NEXT:    movaps {{.*#+}} xmm1 = [1.0E+0]
 ; SSE-NEXT:  .LBB1_3: # %BB0
-; SSE-NEXT:    testq %rbx, %rbx
+; SSE-NEXT:    testl %ebx, %ebx
 ; SSE-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; SSE-NEXT:    jne .LBB1_5
 ; SSE-NEXT:  # %bb.4: # %BB1
@@ -72,9 +72,9 @@ define fp128 @test_select_cc(fp128, fp128) nounwind {
 ;
 ; NOSSE-LABEL: test_select_cc:
 ; NOSSE:       # %bb.0: # %BB0
+; NOSSE-NEXT:    pushq %rbp
 ; NOSSE-NEXT:    pushq %r15
 ; NOSSE-NEXT:    pushq %r14
-; NOSSE-NEXT:    pushq %r13
 ; NOSSE-NEXT:    pushq %r12
 ; NOSSE-NEXT:    pushq %rbx
 ; NOSSE-NEXT:    movq %rcx, %r15
@@ -82,18 +82,18 @@ define fp128 @test_select_cc(fp128, fp128) nounwind {
 ; NOSSE-NEXT:    movq %rsi, %rbx
 ; NOSSE-NEXT:    movq %rdi, %r14
 ; NOSSE-NEXT:    callq __netf2 at PLT
-; NOSSE-NEXT:    movq %rax, %r13
+; NOSSE-NEXT:    movl %eax, %ebp
 ; NOSSE-NEXT:    movq %r14, %rdi
 ; NOSSE-NEXT:    movq %rbx, %rsi
 ; NOSSE-NEXT:    movq %r12, %rdx
 ; NOSSE-NEXT:    movq %r15, %rcx
 ; NOSSE-NEXT:    callq __eqtf2 at PLT
-; NOSSE-NEXT:    movq %rax, %rcx
+; NOSSE-NEXT:    movl %eax, %ecx
 ; NOSSE-NEXT:    xorl %eax, %eax
-; NOSSE-NEXT:    testq %rcx, %rcx
+; NOSSE-NEXT:    testl %ecx, %ecx
 ; NOSSE-NEXT:    movabsq $4611404543450677248, %rdx # imm = 0x3FFF000000000000
 ; NOSSE-NEXT:    cmovneq %rax, %rdx
-; NOSSE-NEXT:    testq %r13, %r13
+; NOSSE-NEXT:    testl %ebp, %ebp
 ; NOSSE-NEXT:    je .LBB1_2
 ; NOSSE-NEXT:  # %bb.1:
 ; NOSSE-NEXT:    movq %r14, %rax
@@ -101,9 +101,9 @@ define fp128 @test_select_cc(fp128, fp128) nounwind {
 ; NOSSE-NEXT:  .LBB1_2: # %BB2
 ; NOSSE-NEXT:    popq %rbx
 ; NOSSE-NEXT:    popq %r12
-; NOSSE-NEXT:    popq %r13
 ; NOSSE-NEXT:    popq %r14
 ; NOSSE-NEXT:    popq %r15
+; NOSSE-NEXT:    popq %rbp
 ; NOSSE-NEXT:    retq
 BB0:
   %a = fcmp oeq fp128 %0, %1
diff --git a/llvm/test/CodeGen/X86/soft-fp-legal-in-HW-reg.ll b/llvm/test/CodeGen/X86/soft-fp-legal-in-HW-reg.ll
index 21f1558bf5f63..f2b0a6e186305 100644
--- a/llvm/test/CodeGen/X86/soft-fp-legal-in-HW-reg.ll
+++ b/llvm/test/CodeGen/X86/soft-fp-legal-in-HW-reg.ll
@@ -19,11 +19,11 @@ define fp128 @TestSelect(fp128 %a, fp128 %b) {
 ; CHECK-NEXT:    movaps %xmm1, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill
 ; CHECK-NEXT:    movaps %xmm0, (%rsp) # 16-byte Spill
 ; CHECK-NEXT:    callq __gttf2 at PLT
-; CHECK-NEXT:    movq %rax, %rbx
+; CHECK-NEXT:    movl %eax, %ebx
 ; CHECK-NEXT:    movaps (%rsp), %xmm0 # 16-byte Reload
 ; CHECK-NEXT:    movaps {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 16-byte Reload
 ; CHECK-NEXT:    callq __subtf3 at PLT
-; CHECK-NEXT:    testq %rbx, %rbx
+; CHECK-NEXT:    testl %ebx, %ebx
 ; CHECK-NEXT:    jg .LBB0_2
 ; CHECK-NEXT:  # %bb.1:
 ; CHECK-NEXT:    xorps %xmm0, %xmm0

>From a29b4d265b50bad2a7708b71e364b96d8701500c Mon Sep 17 00:00:00 2001
From: Trevor Gross <tg at trevorgross.com>
Date: Mon, 27 Apr 2026 04:21:57 -0400
Subject: [PATCH 6/6] add a comment

---
 llvm/include/llvm/CodeGen/TargetLowering.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h
index 5ea97b41922d4..977e722aa5389 100644
--- a/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -1007,7 +1007,8 @@ class LLVM_ABI TargetLoweringBase {
   /// This should match `CMP_RESULT` in `compiler-rt` and `CMPtype` in
   /// `libgcc`. The default return is word-sized. Consider overriding on
   /// targets that have a cheaper comparison or smaller comparison
-  /// encoding at other sizes.
+  /// encoding at other sizes. This affects the ABI so be sure to coordinate
+  /// with other compiler vendors.
   virtual MVT::SimpleValueType
   getCmpLibcallReturnType(const DataLayout &DL) const {
     return MVT::getIntegerVT(getRegisterWidth(DL)).SimpleTy;



More information about the cfe-commits mailing list