[llvm] 53096b7 - [X86][APX] Optimize usub.sat(X,1) to cmp+adc with NDD (#208475)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 18 08:36:02 PDT 2026
Author: AntonyCJ30
Date: 2026-07-18T23:35:57+08:00
New Revision: 53096b7a2d268ab92617436915bc6f9f3cf8d82e
URL: https://github.com/llvm/llvm-project/commit/53096b7a2d268ab92617436915bc6f9f3cf8d82e
DIFF: https://github.com/llvm/llvm-project/commit/53096b7a2d268ab92617436915bc6f9f3cf8d82e.diff
LOG: [X86][APX] Optimize usub.sat(X,1) to cmp+adc with NDD (#208475)
When NDD is available, usub.sat(X, 1) is lowered from xor+sub+cmov (3
insns) to cmp+adc (2 insns).
All X86 tests pass.
Fixes #207888
Co-authored-by: AntonyCJ30 <cj6186609 at gmail@gmail.com>
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/apx/sub.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index f9ec233bd4431..791e04deb9583 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -1395,7 +1395,14 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
setOperationAction(ISD::SUB, MVT::i16, Custom);
setOperationAction(ISD::SUB, MVT::i32, Custom);
}
-
+ if (Subtarget.hasNDD()) {
+ // Enable custom lowering for scalar USUBSAT to optimize usub.sat(X,1)
+ // with cmp+adc when NDD is available.
+ setOperationAction(ISD::USUBSAT, MVT::i8, Custom);
+ setOperationAction(ISD::USUBSAT, MVT::i16, Custom);
+ setOperationAction(ISD::USUBSAT, MVT::i32, Custom);
+ setOperationAction(ISD::USUBSAT, MVT::i64, Custom);
+ }
if (!Subtarget.useSoftFloat() && Subtarget.hasSSE41()) {
for (MVT RoundedTy : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
setOperationAction(ISD::FFLOOR, RoundedTy, Legal);
@@ -29638,7 +29645,6 @@ static SDValue lowerAddSub(SDValue Op, SelectionDAG &DAG,
const X86Subtarget &Subtarget) {
MVT VT = Op.getSimpleValueType();
SDLoc DL(Op);
-
if (VT == MVT::i16 || VT == MVT::i32)
return lowerAddSubToHorizontalOp(Op, DL, DAG, Subtarget);
@@ -29658,6 +29664,22 @@ static SDValue LowerADDSAT_SUBSAT(SDValue Op, SelectionDAG &DAG,
unsigned Opcode = Op.getOpcode();
SDLoc DL(Op);
+ if (Opcode == ISD::USUBSAT && !VT.isVector() && Subtarget.hasNDD()) {
+
+ if (isOneConstant(Y)) {
+ // usub.sat(X,1) == (X==0 ? 0 : X-1). Lower to cmp+adc with NDD.
+ SDValue Sub = DAG.getNode(X86ISD::SUB, DL, DAG.getVTList(VT, MVT::i32), X,
+ DAG.getConstant(1, DL, VT));
+ SDValue EFLAGS = Sub.getValue(1);
+ SDValue MinusOne = DAG.getAllOnesConstant(DL, VT);
+ return DAG.getNode(X86ISD::ADC, DL, DAG.getVTList(VT, MVT::i32), X,
+ MinusOne, EFLAGS);
+ }
+
+ // Scalar USUBSAT was previously Expand. Don't fall through to vector path.
+ return SDValue();
+ }
+
if (VT == MVT::v32i16 || VT == MVT::v64i8 ||
(VT.is256BitVector() && !Subtarget.hasInt256())) {
assert(Op.getSimpleValueType().isInteger() &&
diff --git a/llvm/test/CodeGen/X86/apx/sub.ll b/llvm/test/CodeGen/X86/apx/sub.ll
index 34af966465d93..bfc134ed1ed15 100644
--- a/llvm/test/CodeGen/X86/apx/sub.ll
+++ b/llvm/test/CodeGen/X86/apx/sub.ll
@@ -1,14 +1,19 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd -verify-machineinstrs --show-mc-encoding | FileCheck %s --check-prefixes=CHECK,NDD
; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,+prefer-ndd-mem -verify-machineinstrs --show-mc-encoding | FileCheck %s --check-prefixes=CHECK,MEM
-; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -verify-machineinstrs --show-mc-encoding | FileCheck --check-prefix=NF %s
-; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -x86-enable-apx-for-relocation=true -verify-machineinstrs --show-mc-encoding | FileCheck --check-prefix=NF %s
+; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -verify-machineinstrs --show-mc-encoding | FileCheck --check-prefixes=CHECK,NF %s
+; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+ndd,nf -x86-enable-apx-for-relocation=true -verify-machineinstrs --show-mc-encoding | FileCheck --check-prefixes=CHECK,NF %s
define i8 @sub8rr(i8 noundef %a, i8 noundef %b) {
-; CHECK-LABEL: sub8rr:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x28,0xf7]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub8rr:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x28,0xf7]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub8rr:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subb %sil, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x28,0xf7]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub8rr:
; NF: # %bb.0: # %entry
@@ -20,10 +25,15 @@ entry:
}
define i16 @sub16rr(i16 noundef %a, i16 noundef %b) {
-; CHECK-LABEL: sub16rr:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x29,0xf7]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub16rr:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x29,0xf7]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub16rr:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subw %si, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x29,0xf7]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub16rr:
; NF: # %bb.0: # %entry
@@ -35,10 +45,15 @@ entry:
}
define i32 @sub32rr(i32 noundef %a, i32 noundef %b) {
-; CHECK-LABEL: sub32rr:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subl %esi, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x29,0xf7]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub32rr:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subl %esi, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x29,0xf7]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub32rr:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subl %esi, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x29,0xf7]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub32rr:
; NF: # %bb.0: # %entry
@@ -50,10 +65,15 @@ entry:
}
define i64 @sub64rr(i64 noundef %a, i64 noundef %b) {
-; CHECK-LABEL: sub64rr:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subq %rsi, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x29,0xf7]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub64rr:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subq %rsi, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x29,0xf7]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub64rr:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subq %rsi, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x29,0xf7]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub64rr:
; NF: # %bb.0: # %entry
@@ -161,10 +181,15 @@ entry:
}
define i16 @sub16ri8(i16 noundef %a) {
-; CHECK-LABEL: sub16ri8:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subw $-128, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x83,0xef,0x80]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub16ri8:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subw $-128, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x83,0xef,0x80]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub16ri8:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subw $-128, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x83,0xef,0x80]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub16ri8:
; NF: # %bb.0: # %entry
@@ -176,10 +201,15 @@ entry:
}
define i32 @sub32ri8(i32 noundef %a) {
-; CHECK-LABEL: sub32ri8:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subl $-128, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x83,0xef,0x80]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub32ri8:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subl $-128, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x83,0xef,0x80]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub32ri8:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subl $-128, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x83,0xef,0x80]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub32ri8:
; NF: # %bb.0: # %entry
@@ -191,10 +221,15 @@ entry:
}
define i64 @sub64ri8(i64 noundef %a) {
-; CHECK-LABEL: sub64ri8:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subq $-128, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x83,0xef,0x80]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub64ri8:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subq $-128, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x83,0xef,0x80]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub64ri8:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subq $-128, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x83,0xef,0x80]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub64ri8:
; NF: # %bb.0: # %entry
@@ -206,10 +241,15 @@ entry:
}
define i8 @sub8ri(i8 noundef %a) {
-; CHECK-LABEL: sub8ri:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addb $-123, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x80,0xc7,0x85]
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub8ri:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: addb $-123, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x80,0xc7,0x85]
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub8ri:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: addb $-123, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x80,0xc7,0x85]
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub8ri:
; NF: # %bb.0: # %entry
@@ -221,11 +261,17 @@ entry:
}
define i16 @sub16ri(i16 noundef %a) {
-; CHECK-LABEL: sub16ri:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: addw $-1234, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x81,0xc7,0x2e,0xfb]
-; CHECK-NEXT: # imm = 0xFB2E
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub16ri:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: addw $-1234, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x81,0xc7,0x2e,0xfb]
+; NDD-NEXT: # imm = 0xFB2E
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub16ri:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: addw $-1234, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x81,0xc7,0x2e,0xfb]
+; MEM-NEXT: # imm = 0xFB2E
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub16ri:
; NF: # %bb.0: # %entry
@@ -242,22 +288,23 @@ define i32 @sub32ri(i32 noundef %a) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: leal -123456(%rdi), %eax # encoding: [0x8d,0x87,0xc0,0x1d,0xfe,0xff]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub32ri:
-; NF: # %bb.0: # %entry
-; NF-NEXT: leal -123456(%rdi), %eax # encoding: [0x8d,0x87,0xc0,0x1d,0xfe,0xff]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = sub i32 %a, 123456
ret i32 %sub
}
define i64 @sub64ri(i64 noundef %a) {
-; CHECK-LABEL: sub64ri:
-; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: subq $-2147483648, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x81,0xef,0x00,0x00,0x00,0x80]
-; CHECK-NEXT: # imm = 0x80000000
-; CHECK-NEXT: retq # encoding: [0xc3]
+; NDD-LABEL: sub64ri:
+; NDD: # %bb.0: # %entry
+; NDD-NEXT: subq $-2147483648, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x81,0xef,0x00,0x00,0x00,0x80]
+; NDD-NEXT: # imm = 0x80000000
+; NDD-NEXT: retq # encoding: [0xc3]
+;
+; MEM-LABEL: sub64ri:
+; MEM: # %bb.0: # %entry
+; MEM-NEXT: subq $-2147483648, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x81,0xef,0x00,0x00,0x00,0x80]
+; MEM-NEXT: # imm = 0x80000000
+; MEM-NEXT: retq # encoding: [0xc3]
;
; NF-LABEL: sub64ri:
; NF: # %bb.0: # %entry
@@ -545,15 +592,6 @@ define i8 @subflag8rr(i8 noundef %a, i8 noundef %b) {
; CHECK-NEXT: cmovael %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc1]
; CHECK-NEXT: # kill: def $al killed $al killed $eax
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag8rr:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subb %sil, %dil, %cl # encoding: [0x62,0xf4,0x74,0x18,0x28,0xf7]
-; NF-NEXT: movzbl %cl, %ecx # encoding: [0x0f,0xb6,0xc9]
-; NF-NEXT: cmovael %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc1]
-; NF-NEXT: # kill: def $al killed $al killed $eax
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i8 @llvm.usub.sat.i8(i8 %a, i8 %b)
ret i8 %sub
@@ -567,14 +605,6 @@ define i16 @subflag16rr(i16 noundef %a, i16 noundef %b) {
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag16rr:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subw %si, %di # EVEX TO LEGACY Compression encoding: [0x66,0x29,0xf7]
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: # kill: def $ax killed $ax killed $eax
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i16 @llvm.usub.sat.i16(i16 %a, i16 %b)
ret i16 %sub
@@ -587,13 +617,6 @@ define i32 @subflag32rr(i32 noundef %a, i32 noundef %b) {
; CHECK-NEXT: subl %esi, %edi # EVEX TO LEGACY Compression encoding: [0x29,0xf7]
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag32rr:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subl %esi, %edi # EVEX TO LEGACY Compression encoding: [0x29,0xf7]
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 %b)
ret i32 %sub
@@ -606,13 +629,6 @@ define i64 @subflag64rr(i64 noundef %a, i64 noundef %b) {
; CHECK-NEXT: subq %rsi, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x29,0xf7]
; CHECK-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag64rr:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subq %rsi, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x29,0xf7]
-; NF-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i64 @llvm.usub.sat.i64(i64 %a, i64 %b)
ret i64 %sub
@@ -743,14 +759,6 @@ define i16 @subflag16ri8(i16 noundef %a) {
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag16ri8:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subw $123, %di # EVEX TO LEGACY Compression encoding: [0x66,0x83,0xef,0x7b]
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: # kill: def $ax killed $ax killed $eax
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i16 @llvm.usub.sat.i16(i16 %a, i16 123)
ret i16 %sub
@@ -763,13 +771,6 @@ define i32 @subflag32ri8(i32 noundef %a) {
; CHECK-NEXT: subl $123, %edi # EVEX TO LEGACY Compression encoding: [0x83,0xef,0x7b]
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag32ri8:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subl $123, %edi # EVEX TO LEGACY Compression encoding: [0x83,0xef,0x7b]
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 123)
ret i32 %sub
@@ -782,13 +783,6 @@ define i64 @subflag64ri8(i64 noundef %a) {
; CHECK-NEXT: subq $123, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xef,0x7b]
; CHECK-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag64ri8:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subq $123, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x83,0xef,0x7b]
-; NF-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i64 @llvm.usub.sat.i64(i64 %a, i64 123)
ret i64 %sub
@@ -803,15 +797,6 @@ define i8 @subflag8ri(i8 noundef %a) {
; CHECK-NEXT: cmovael %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc1]
; CHECK-NEXT: # kill: def $al killed $al killed $eax
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag8ri:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subb $123, %dil, %cl # encoding: [0x62,0xf4,0x74,0x18,0x80,0xef,0x7b]
-; NF-NEXT: movzbl %cl, %ecx # encoding: [0x0f,0xb6,0xc9]
-; NF-NEXT: cmovael %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc1]
-; NF-NEXT: # kill: def $al killed $al killed $eax
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i8 @llvm.usub.sat.i8(i8 %a, i8 123)
ret i8 %sub
@@ -826,15 +811,6 @@ define i16 @subflag16ri(i16 noundef %a) {
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: # kill: def $ax killed $ax killed $eax
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag16ri:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subw $1234, %di # EVEX TO LEGACY Compression encoding: [0x66,0x81,0xef,0xd2,0x04]
-; NF-NEXT: # imm = 0x4D2
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: # kill: def $ax killed $ax killed $eax
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i16 @llvm.usub.sat.i16(i16 %a, i16 1234)
ret i16 %sub
@@ -848,14 +824,6 @@ define i32 @subflag32ri(i32 noundef %a) {
; CHECK-NEXT: # imm = 0x1E240
; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag32ri:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subl $123456, %edi # EVEX TO LEGACY Compression encoding: [0x81,0xef,0x40,0xe2,0x01,0x00]
-; NF-NEXT: # imm = 0x1E240
-; NF-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 123456)
ret i32 %sub
@@ -869,14 +837,6 @@ define i64 @subflag64ri(i64 noundef %a) {
; CHECK-NEXT: # imm = 0x1E240
; CHECK-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: subflag64ri:
-; NF: # %bb.0: # %entry
-; NF-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
-; NF-NEXT: subq $123456, %rdi # EVEX TO LEGACY Compression encoding: [0x48,0x81,0xef,0x40,0xe2,0x01,0x00]
-; NF-NEXT: # imm = 0x1E240
-; NF-NEXT: cmovaeq %rdi, %rax # EVEX TO LEGACY Compression encoding: [0x48,0x0f,0x43,0xc7]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%sub = call i64 @llvm.usub.sat.i64(i64 %a, i64 123456)
ret i64 %sub
@@ -902,22 +862,6 @@ define void @sub64ri_reloc(i64 %val) {
; CHECK-NEXT: .cfi_def_cfa_offset 8
; CHECK-NEXT: .LBB41_2: # %f
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub64ri_reloc:
-; NF: # %bb.0:
-; NF-NEXT: cmpq $val, %rdi # encoding: [0x48,0x81,0xff,A,A,A,A]
-; NF-NEXT: # fixup A - offset: 3, value: val, kind: reloc_signed_4byte
-; NF-NEXT: jbe .LBB41_2 # encoding: [0x76,A]
-; NF-NEXT: # fixup A - offset: 1, value: .LBB41_2, kind: FK_PCRel_1
-; NF-NEXT: # %bb.1: # %t
-; NF-NEXT: pushq %rax # encoding: [0x50]
-; NF-NEXT: .cfi_def_cfa_offset 16
-; NF-NEXT: callq f at PLT # encoding: [0xe8,A,A,A,A]
-; NF-NEXT: # fixup A - offset: 1, value: f at PLT, kind: FK_PCRel_4
-; NF-NEXT: popq %rax # encoding: [0x58]
-; NF-NEXT: .cfi_def_cfa_offset 8
-; NF-NEXT: .LBB41_2: # %f
-; NF-NEXT: retq # encoding: [0xc3]
%cmp = icmp ugt i64 %val, ptrtoint (ptr @val to i64)
br i1 %cmp, label %t, label %f
@@ -934,11 +878,6 @@ define void @sub8mr_legacy(ptr %a, i8 noundef %b) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subb %sil, (%rdi) # encoding: [0x40,0x28,0x37]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub8mr_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: subb %sil, (%rdi) # encoding: [0x40,0x28,0x37]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i8, ptr %a
%sub = sub i8 %t, %b
@@ -951,11 +890,6 @@ define void @sub16mr_legacy(ptr %a, i16 noundef %b) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subw %si, (%rdi) # encoding: [0x66,0x29,0x37]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub16mr_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: subw %si, (%rdi) # encoding: [0x66,0x29,0x37]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i16, ptr %a
%sub = sub i16 %t, %b
@@ -968,11 +902,6 @@ define void @sub32mr_legacy(ptr %a, i32 noundef %b) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subl %esi, (%rdi) # encoding: [0x29,0x37]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub32mr_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: subl %esi, (%rdi) # encoding: [0x29,0x37]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i32, ptr %a
%sub = sub i32 %t, %b
@@ -985,11 +914,6 @@ define void @sub64mr_legacy(ptr %a, i64 noundef %b) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: subq %rsi, (%rdi) # encoding: [0x48,0x29,0x37]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub64mr_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: subq %rsi, (%rdi) # encoding: [0x48,0x29,0x37]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i64, ptr %a
%sub = sub i64 %t, %b
@@ -1002,11 +926,6 @@ define void @sub8mi_legacy(ptr %a) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addb $-123, (%rdi) # encoding: [0x80,0x07,0x85]
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub8mi_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: addb $-123, (%rdi) # encoding: [0x80,0x07,0x85]
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i8, ptr %a
%sub = sub nsw i8 %t, 123
@@ -1020,12 +939,6 @@ define void @sub16mi_legacy(ptr %a) {
; CHECK-NEXT: addw $-1234, (%rdi) # encoding: [0x66,0x81,0x07,0x2e,0xfb]
; CHECK-NEXT: # imm = 0xFB2E
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub16mi_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: addw $-1234, (%rdi) # encoding: [0x66,0x81,0x07,0x2e,0xfb]
-; NF-NEXT: # imm = 0xFB2E
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i16, ptr %a
%sub = sub nsw i16 %t, 1234
@@ -1039,12 +952,6 @@ define void @sub32mi_legacy(ptr %a) {
; CHECK-NEXT: addl $-123456, (%rdi) # encoding: [0x81,0x07,0xc0,0x1d,0xfe,0xff]
; CHECK-NEXT: # imm = 0xFFFE1DC0
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub32mi_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: addl $-123456, (%rdi) # encoding: [0x81,0x07,0xc0,0x1d,0xfe,0xff]
-; NF-NEXT: # imm = 0xFFFE1DC0
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i32, ptr %a
%sub = sub nsw i32 %t, 123456
@@ -1058,12 +965,6 @@ define void @sub64mi_legacy(ptr %a) {
; CHECK-NEXT: addq $-123456, (%rdi) # encoding: [0x48,0x81,0x07,0xc0,0x1d,0xfe,0xff]
; CHECK-NEXT: # imm = 0xFFFE1DC0
; CHECK-NEXT: retq # encoding: [0xc3]
-;
-; NF-LABEL: sub64mi_legacy:
-; NF: # %bb.0: # %entry
-; NF-NEXT: addq $-123456, (%rdi) # encoding: [0x48,0x81,0x07,0xc0,0x1d,0xfe,0xff]
-; NF-NEXT: # imm = 0xFFFE1DC0
-; NF-NEXT: retq # encoding: [0xc3]
entry:
%t= load i64, ptr %a
%sub = sub nsw i64 %t, 123456
@@ -1238,3 +1139,95 @@ bb2: ; preds = %bb2, %bb1
store ptr null, ptr %arg2, align 8
br i1 %arg3, label %bb1, label %bb2
}
+;
+define i8 @usubsat8_const1(i8 noundef %a) {
+; CHECK-LABEL: usubsat8_const1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: cmpb $1, %dil # encoding: [0x40,0x80,0xff,0x01]
+; CHECK-NEXT: adcb $-1, %dil, %al # encoding: [0x62,0xf4,0x7c,0x18,0x80,0xd7,0xff]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i8 @llvm.usub.sat.i8(i8 %a, i8 1)
+ ret i8 %sub
+}
+
+define i16 @usubsat16_const1(i16 noundef %a) {
+; CHECK-LABEL: usubsat16_const1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: cmpw $1, %di # encoding: [0x66,0x83,0xff,0x01]
+; CHECK-NEXT: adcw $-1, %di, %ax # encoding: [0x62,0xf4,0x7d,0x18,0x83,0xd7,0xff]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i16 @llvm.usub.sat.i16(i16 %a, i16 1)
+ ret i16 %sub
+}
+
+define i32 @usubsat32_const1(i32 noundef %a) {
+; CHECK-LABEL: usubsat32_const1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: cmpl $1, %edi # encoding: [0x83,0xff,0x01]
+; CHECK-NEXT: adcl $-1, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x83,0xd7,0xff]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 1)
+ ret i32 %sub
+}
+
+define i64 @usubsat64_const1(i64 noundef %a) {
+; CHECK-LABEL: usubsat64_const1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: cmpq $1, %rdi # encoding: [0x48,0x83,0xff,0x01]
+; CHECK-NEXT: adcq $-1, %rdi, %rax # encoding: [0x62,0xf4,0xfc,0x18,0x83,0xd7,0xff]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i64 @llvm.usub.sat.i64(i64 %a, i64 1)
+ ret i64 %sub
+}
+
+define i32 @usubsat32_var(i32 noundef %a, i32 noundef %b) {
+; CHECK-LABEL: usubsat32_var:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
+; CHECK-NEXT: subl %esi, %edi # EVEX TO LEGACY Compression encoding: [0x29,0xf7]
+; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 %b)
+ ret i32 %sub
+}
+
+define i32 @usubsat32_const123(i32 noundef %a) {
+; CHECK-LABEL: usubsat32_const123:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0]
+; CHECK-NEXT: subl $123, %edi # EVEX TO LEGACY Compression encoding: [0x83,0xef,0x7b]
+; CHECK-NEXT: cmovael %edi, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x43,0xc7]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %sub = call i32 @llvm.usub.sat.i32(i32 %a, i32 123)
+ ret i32 %sub
+}
+
+define i32 @uaddsat32_const1(i32 noundef %a) {
+; CHECK-LABEL: uaddsat32_const1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: incl %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0xff,0xc7]
+; CHECK-NEXT: movl $-1, %ecx # encoding: [0xb9,0xff,0xff,0xff,0xff]
+; CHECK-NEXT: cmovel %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x44,0xc1]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %add = call i32 @llvm.uadd.sat.i32(i32 %a, i32 1)
+ ret i32 %add
+}
+
+define i32 @uaddsat32_const_neg1(i32 noundef %a) {
+; CHECK-LABEL: uaddsat32_const_neg1:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: addl $-1, %edi, %eax # encoding: [0x62,0xf4,0x7c,0x18,0x83,0xc7,0xff]
+; CHECK-NEXT: movl $-1, %ecx # encoding: [0xb9,0xff,0xff,0xff,0xff]
+; CHECK-NEXT: cmovbl %ecx, %eax # EVEX TO LEGACY Compression encoding: [0x0f,0x42,0xc1]
+; CHECK-NEXT: retq # encoding: [0xc3]
+entry:
+ %add = call i32 @llvm.uadd.sat.i32(i32 %a, i32 -1)
+ ret i32 %add
+}
More information about the llvm-commits
mailing list