[llvm] [X86] Enable preferZeroCompareBranch() (PR #219919)

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 31 02:18:04 PDT 2026


https://github.com/zmodem created https://github.com/llvm/llvm-project/pull/219919

This makes CodeGenPrepare reorganize code such as:

```
%c = icmp eq i32 %x, 10
br %c, then, else
%a = add i32 %x, -10
```

into

```
%a = add i32 %x, -10
%cmp = icmp eq %a, 0
%br %cmp, then, else
```

so that the zero-compare and branch gets lowered to a JCC based on the flags from the arithmetic instruction.

This was already enabled for ARM, SystemZ and RISC-V, but seems a good fit for X86 too.

>From 63cf45102e8345f024bbf76ca29705a2e54dcce3 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Wed, 19 Aug 2026 11:40:12 +0200
Subject: [PATCH 1/4] create llvm/test/CodeGen/X86/branch-on-zero.ll

based on
llvm/test/Transforms/CodeGenPrepare/ARM/branch-on-zero.ll and
llvm/test/CodeGen/RISCV/select-constant-xor.ll
---
 llvm/test/CodeGen/X86/branch-on-zero.ll | 215 ++++++++++++++++++++++++
 1 file changed, 215 insertions(+)
 create mode 100644 llvm/test/CodeGen/X86/branch-on-zero.ll

diff --git a/llvm/test/CodeGen/X86/branch-on-zero.ll b/llvm/test/CodeGen/X86/branch-on-zero.ll
new file mode 100644
index 0000000000000..f4ca468675d03
--- /dev/null
+++ b/llvm/test/CodeGen/X86/branch-on-zero.ll
@@ -0,0 +1,215 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple x86_64-unknown-linux-gnu -o - %s | FileCheck %s --check-prefix=CHECK64
+; RUN: llc -mtriple i686-unknown-linux-gnu -o - %s   | FileCheck %s --check-prefix=CHECK32
+
+define i32 @lshr3_then(i32 %a) {
+entry:
+  %c = icmp ult i32 %a, 8
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 0
+
+else:
+  %l = lshr i32 %a, 3
+  ret i32 %l
+}
+
+define i32 @lshr5_else(i32 %a) {
+entry:
+  %c = icmp ult i32 %a, 32
+  br i1 %c, label %then, label %else
+
+then:
+  %l = lshr i32 %a, 5
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @lshr2_entry(i32 %a) {
+entry:
+  %l = lshr i32 %a, 1
+  %c = icmp ult i32 %a, 2
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @lshr5mismatch(i32 %a) {
+entry:
+  %c = icmp ult i32 %a, 17
+  br i1 %c, label %then, label %else
+
+then:
+  %l = lshr i32 %a, 5
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @ashr5_else(i32 %a) {
+entry:
+  %c = icmp ult i32 %a, 32
+  br i1 %c, label %then, label %else
+
+then:
+  %l = ashr i32 %a, 5
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @add10_else(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, 10
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 0
+
+else:
+  %l = add i32 %a, 10
+  ret i32 %l
+}
+
+define i32 @addm10_then(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, 10
+  br i1 %c, label %then, label %else
+
+then:
+  %l = add i32 %a, -10
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @add_missmatch(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, 10
+  br i1 %c, label %then, label %else
+
+then:
+  %l = add i32 %a, 10
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i32 @sub10_else(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, 10
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 0
+
+else:
+  %l = sub i32 %a, 10
+  ret i32 %l
+}
+
+define i32 @sub10_else_drop_nuw(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, 10
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 0
+
+else:
+  %l = sub nuw i32 %a, 10
+  ret i32 %l
+}
+
+define i32 @subm10_then(i32 %a) {
+entry:
+  %c = icmp eq i32 %a, -10
+  br i1 %c, label %then, label %else
+
+then:
+  %l = sub i32 %a, -10
+  ret i32 %l
+
+else:
+  ret i32 0
+}
+
+define i64 @lshr64(i64 %a) {
+entry:
+  %c = icmp ult i64 %a, 1099511627776
+  br i1 %c, label %then, label %else
+
+then:
+  ret i64 0
+
+else:
+  %l = lshr i64 %a, 40
+  ret i64 %l
+}
+
+define i128 @lshr128(i128 %a) {
+entry:
+  %c = icmp ult i128 %a, 36893488147419103232
+  br i1 %c, label %then, label %else
+
+then:
+  ret i128 0
+
+else:
+  %l = lshr i128 %a, 65
+  ret i128 %l
+}
+
+define i32 @addm1_dom(i32 %a) {
+entry:
+  %c1 = icmp eq i32 %a, 100
+  br i1 %c1, label %if, label %else
+
+if:
+  %c = icmp eq i32 %a, -1
+  br i1 %c, label %then, label %else
+
+then:
+  ret i32 0
+
+else:
+  %l = add i32 %a, 1
+  ret i32 %l
+}
+
+define i32 @xor_branch_imm_ret(i32 %x) {
+entry:
+  %cmp.not = icmp eq i32 %x, -1365
+  br i1 %cmp.not, label %if.end, label %if.then
+if.then:
+  %xor = xor i32 %x, -1365
+  ret i32 %xor
+if.end:
+  tail call void @other()
+  unreachable
+}
+
+define i32 @xor_branch_ret(i32 %x) {
+entry:
+  %cmp.not = icmp eq i32 %x, 2048
+  br i1 %cmp.not, label %if.end, label %if.then
+if.then:
+  %xor = xor i32 %x, 2048
+  ret i32 %xor
+if.end:
+  tail call void @other()
+  unreachable
+}
+
+declare void @other()

>From f9049baf48bc0e0726f2a52bf70722434b0dfcdc Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Mon, 31 Aug 2026 10:15:42 +0200
Subject: [PATCH 2/4] pre-commit expectations for
 llvm/test/CodeGen/X86/branch-on-zero.ll

---
 llvm/test/CodeGen/X86/branch-on-zero.ll | 415 ++++++++++++++++++++++++
 1 file changed, 415 insertions(+)

diff --git a/llvm/test/CodeGen/X86/branch-on-zero.ll b/llvm/test/CodeGen/X86/branch-on-zero.ll
index f4ca468675d03..8171d03cf9d13 100644
--- a/llvm/test/CodeGen/X86/branch-on-zero.ll
+++ b/llvm/test/CodeGen/X86/branch-on-zero.ll
@@ -3,6 +3,29 @@
 ; RUN: llc -mtriple i686-unknown-linux-gnu -o - %s   | FileCheck %s --check-prefix=CHECK32
 
 define i32 @lshr3_then(i32 %a) {
+; CHECK64-LABEL: lshr3_then:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $7, %edi
+; CHECK64-NEXT:    ja .LBB0_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB0_2: # %else
+; CHECK64-NEXT:    shrl $3, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr3_then:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $7, %eax
+; CHECK32-NEXT:    ja .LBB0_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB0_2: # %else
+; CHECK32-NEXT:    shrl $3, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 8
   br i1 %c, label %then, label %else
@@ -16,6 +39,29 @@ else:
 }
 
 define i32 @lshr5_else(i32 %a) {
+; CHECK64-LABEL: lshr5_else:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $31, %edi
+; CHECK64-NEXT:    ja .LBB1_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    shrl $5, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB1_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr5_else:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $31, %eax
+; CHECK32-NEXT:    ja .LBB1_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    shrl $5, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB1_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 32
   br i1 %c, label %then, label %else
@@ -29,6 +75,29 @@ else:
 }
 
 define i32 @lshr2_entry(i32 %a) {
+; CHECK64-LABEL: lshr2_entry:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $1, %edi
+; CHECK64-NEXT:    ja .LBB2_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    shrl %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB2_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr2_entry:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $1, %eax
+; CHECK32-NEXT:    ja .LBB2_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    shrl %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB2_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %l = lshr i32 %a, 1
   %c = icmp ult i32 %a, 2
@@ -42,6 +111,29 @@ else:
 }
 
 define i32 @lshr5mismatch(i32 %a) {
+; CHECK64-LABEL: lshr5mismatch:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $16, %edi
+; CHECK64-NEXT:    ja .LBB3_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    shrl $5, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB3_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr5mismatch:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $16, %eax
+; CHECK32-NEXT:    ja .LBB3_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    shrl $5, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB3_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 17
   br i1 %c, label %then, label %else
@@ -55,6 +147,29 @@ else:
 }
 
 define i32 @ashr5_else(i32 %a) {
+; CHECK64-LABEL: ashr5_else:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $31, %edi
+; CHECK64-NEXT:    ja .LBB4_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    sarl $5, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB4_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: ashr5_else:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $31, %eax
+; CHECK32-NEXT:    ja .LBB4_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    sarl $5, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB4_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 32
   br i1 %c, label %then, label %else
@@ -68,6 +183,29 @@ else:
 }
 
 define i32 @add10_else(i32 %a) {
+; CHECK64-LABEL: add10_else:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $10, %edi
+; CHECK64-NEXT:    jne .LBB5_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB5_2: # %else
+; CHECK64-NEXT:    addl $10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: add10_else:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $10, %eax
+; CHECK32-NEXT:    jne .LBB5_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB5_2: # %else
+; CHECK32-NEXT:    addl $10, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -81,6 +219,29 @@ else:
 }
 
 define i32 @addm10_then(i32 %a) {
+; CHECK64-LABEL: addm10_then:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $10, %edi
+; CHECK64-NEXT:    jne .LBB6_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    addl $-10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB6_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: addm10_then:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $10, %eax
+; CHECK32-NEXT:    jne .LBB6_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    addl $-10, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB6_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -94,6 +255,29 @@ else:
 }
 
 define i32 @add_missmatch(i32 %a) {
+; CHECK64-LABEL: add_missmatch:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $10, %edi
+; CHECK64-NEXT:    jne .LBB7_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    addl $10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB7_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: add_missmatch:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $10, %eax
+; CHECK32-NEXT:    jne .LBB7_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    addl $10, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB7_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -107,6 +291,29 @@ else:
 }
 
 define i32 @sub10_else(i32 %a) {
+; CHECK64-LABEL: sub10_else:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $10, %edi
+; CHECK64-NEXT:    jne .LBB8_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB8_2: # %else
+; CHECK64-NEXT:    addl $-10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: sub10_else:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $10, %eax
+; CHECK32-NEXT:    jne .LBB8_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB8_2: # %else
+; CHECK32-NEXT:    addl $-10, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -120,6 +327,29 @@ else:
 }
 
 define i32 @sub10_else_drop_nuw(i32 %a) {
+; CHECK64-LABEL: sub10_else_drop_nuw:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $10, %edi
+; CHECK64-NEXT:    jne .LBB9_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB9_2: # %else
+; CHECK64-NEXT:    addl $-10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: sub10_else_drop_nuw:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $10, %eax
+; CHECK32-NEXT:    jne .LBB9_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB9_2: # %else
+; CHECK32-NEXT:    addl $-10, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -133,6 +363,29 @@ else:
 }
 
 define i32 @subm10_then(i32 %a) {
+; CHECK64-LABEL: subm10_then:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $-10, %edi
+; CHECK64-NEXT:    jne .LBB10_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    addl $10, %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB10_2: # %else
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: subm10_then:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $-10, %eax
+; CHECK32-NEXT:    jne .LBB10_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    addl $10, %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB10_2: # %else
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, -10
   br i1 %c, label %then, label %else
@@ -146,6 +399,30 @@ else:
 }
 
 define i64 @lshr64(i64 %a) {
+; CHECK64-LABEL: lshr64:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    shrq $40, %rdi
+; CHECK64-NEXT:    jne .LBB11_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB11_2: # %else
+; CHECK64-NEXT:    movq %rdi, %rax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr64:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    testl $-256, %eax
+; CHECK32-NEXT:    jne .LBB11_2
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    xorl %edx, %edx
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB11_2: # %else
+; CHECK32-NEXT:    shrl $8, %eax
+; CHECK32-NEXT:    xorl %edx, %edx
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i64 %a, 1099511627776
   br i1 %c, label %then, label %else
@@ -159,6 +436,59 @@ else:
 }
 
 define i128 @lshr128(i128 %a) {
+; CHECK64-LABEL: lshr128:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpq $1, %rsi
+; CHECK64-NEXT:    ja .LBB12_2
+; CHECK64-NEXT:  # %bb.1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    xorl %edx, %edx
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB12_2: # %else
+; CHECK64-NEXT:    shrq %rsi
+; CHECK64-NEXT:    movq %rsi, %rax
+; CHECK64-NEXT:    xorl %edx, %edx
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: lshr128:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    pushl %edi
+; CHECK32-NEXT:    .cfi_def_cfa_offset 8
+; CHECK32-NEXT:    pushl %esi
+; CHECK32-NEXT:    .cfi_def_cfa_offset 12
+; CHECK32-NEXT:    pushl %eax
+; CHECK32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK32-NEXT:    .cfi_offset %esi, -12
+; CHECK32-NEXT:    .cfi_offset %edi, -8
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; CHECK32-NEXT:    xorl %esi, %esi
+; CHECK32-NEXT:    movl $1, %edi
+; CHECK32-NEXT:    cmpl %ecx, %edi
+; CHECK32-NEXT:    sbbl %edx, %esi
+; CHECK32-NEXT:    jb .LBB12_3
+; CHECK32-NEXT:  # %bb.1: # %then
+; CHECK32-NEXT:    movl $0, 12(%eax)
+; CHECK32-NEXT:    movl $0, 8(%eax)
+; CHECK32-NEXT:    movl $0, 4(%eax)
+; CHECK32-NEXT:    movl $0, (%eax)
+; CHECK32-NEXT:    jmp .LBB12_2
+; CHECK32-NEXT:  .LBB12_3: # %else
+; CHECK32-NEXT:    shrdl $1, %edx, %ecx
+; CHECK32-NEXT:    shrl %edx
+; CHECK32-NEXT:    movl %edx, 4(%eax)
+; CHECK32-NEXT:    movl %ecx, (%eax)
+; CHECK32-NEXT:    movl $0, 12(%eax)
+; CHECK32-NEXT:    movl $0, 8(%eax)
+; CHECK32-NEXT:  .LBB12_2: # %then
+; CHECK32-NEXT:    addl $4, %esp
+; CHECK32-NEXT:    .cfi_def_cfa_offset 12
+; CHECK32-NEXT:    popl %esi
+; CHECK32-NEXT:    .cfi_def_cfa_offset 8
+; CHECK32-NEXT:    popl %edi
+; CHECK32-NEXT:    .cfi_def_cfa_offset 4
+; CHECK32-NEXT:    retl $4
 entry:
   %c = icmp ult i128 %a, 36893488147419103232
   br i1 %c, label %then, label %else
@@ -172,6 +502,35 @@ else:
 }
 
 define i32 @addm1_dom(i32 %a) {
+; CHECK64-LABEL: addm1_dom:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $100, %edi
+; CHECK64-NEXT:    jne .LBB13_3
+; CHECK64-NEXT:  # %bb.1: # %if
+; CHECK64-NEXT:    cmpl $-1, %edi
+; CHECK64-NEXT:    je .LBB13_2
+; CHECK64-NEXT:  .LBB13_3: # %else
+; CHECK64-NEXT:    incl %edi
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB13_2: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
+;
+; CHECK32-LABEL: addm1_dom:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $100, %eax
+; CHECK32-NEXT:    jne .LBB13_3
+; CHECK32-NEXT:  # %bb.1: # %if
+; CHECK32-NEXT:    cmpl $-1, %eax
+; CHECK32-NEXT:    je .LBB13_2
+; CHECK32-NEXT:  .LBB13_3: # %else
+; CHECK32-NEXT:    incl %eax
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB13_2: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    retl
 entry:
   %c1 = icmp eq i32 %a, 100
   br i1 %c1, label %if, label %else
@@ -189,6 +548,34 @@ else:
 }
 
 define i32 @xor_branch_imm_ret(i32 %x) {
+; CHECK64-LABEL: xor_branch_imm_ret:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $-1365, %edi # imm = 0xFAAB
+; CHECK64-NEXT:    je .LBB14_2
+; CHECK64-NEXT:  # %bb.1: # %if.then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    xorl $-1365, %eax # imm = 0xFAAB
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB14_2: # %if.end
+; CHECK64-NEXT:    pushq %rax
+; CHECK64-NEXT:    .cfi_def_cfa_offset 16
+; CHECK64-NEXT:    callq other at PLT
+;
+; CHECK32-LABEL: xor_branch_imm_ret:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    subl $12, %esp
+; CHECK32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $-1365, %eax # imm = 0xFAAB
+; CHECK32-NEXT:    je .LBB14_2
+; CHECK32-NEXT:  # %bb.1: # %if.then
+; CHECK32-NEXT:    xorl $-1365, %eax # imm = 0xFAAB
+; CHECK32-NEXT:    addl $12, %esp
+; CHECK32-NEXT:    .cfi_def_cfa_offset 4
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB14_2: # %if.end
+; CHECK32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK32-NEXT:    calll other at PLT
 entry:
   %cmp.not = icmp eq i32 %x, -1365
   br i1 %cmp.not, label %if.end, label %if.then
@@ -201,6 +588,34 @@ if.end:
 }
 
 define i32 @xor_branch_ret(i32 %x) {
+; CHECK64-LABEL: xor_branch_ret:
+; CHECK64:       # %bb.0: # %entry
+; CHECK64-NEXT:    cmpl $2048, %edi # imm = 0x800
+; CHECK64-NEXT:    je .LBB15_2
+; CHECK64-NEXT:  # %bb.1: # %if.then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    xorl $2048, %eax # imm = 0x800
+; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB15_2: # %if.end
+; CHECK64-NEXT:    pushq %rax
+; CHECK64-NEXT:    .cfi_def_cfa_offset 16
+; CHECK64-NEXT:    callq other at PLT
+;
+; CHECK32-LABEL: xor_branch_ret:
+; CHECK32:       # %bb.0: # %entry
+; CHECK32-NEXT:    subl $12, %esp
+; CHECK32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; CHECK32-NEXT:    cmpl $2048, %eax # imm = 0x800
+; CHECK32-NEXT:    je .LBB15_2
+; CHECK32-NEXT:  # %bb.1: # %if.then
+; CHECK32-NEXT:    xorl $2048, %eax # imm = 0x800
+; CHECK32-NEXT:    addl $12, %esp
+; CHECK32-NEXT:    .cfi_def_cfa_offset 4
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB15_2: # %if.end
+; CHECK32-NEXT:    .cfi_def_cfa_offset 16
+; CHECK32-NEXT:    calll other at PLT
 entry:
   %cmp.not = icmp eq i32 %x, 2048
   br i1 %cmp.not, label %if.end, label %if.then

>From 956ce1bfe70fd3339e0fbdb2b8e3db8865bab441 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Thu, 30 Apr 2026 16:21:58 +0200
Subject: [PATCH 3/4] set preferZeroCompareBranch() to true for x86

---
 llvm/lib/Target/X86/X86ISelLowering.cpp | 4 ++++
 llvm/lib/Target/X86/X86ISelLowering.h   | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index fbebb55cb8c51..fcd9d2c9f6212 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -3761,6 +3761,10 @@ bool X86TargetLowering::isCtlzFast() const {
   return Subtarget.hasFastLZCNT();
 }
 
+bool X86TargetLowering::preferZeroCompareBranch() const {
+  return true;
+}
+
 bool X86TargetLowering::isMaskAndCmp0FoldingBeneficial(
     const Instruction &AndI) const {
   return true;
diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h
index b220c1bbe7bc7..5215bb0704dca 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.h
+++ b/llvm/lib/Target/X86/X86ISelLowering.h
@@ -238,6 +238,8 @@ namespace llvm {
 
     bool isCtlzFast() const override;
 
+    bool preferZeroCompareBranch() const override;
+
     bool isMultiStoresCheaperThanBitsMerge(EVT LTy, EVT HTy) const override {
       // If the pair to store is a mixture of float and int values, we will
       // save two bitwise instructions and one float-to-int instruction and

>From d14866459db7c8470b2bd520c0b65cdf3fe385cb Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Mon, 31 Aug 2026 10:17:39 +0200
Subject: [PATCH 4/4] update expectations in
 llvm/test/CodeGen/X86/branch-on-zero.ll

---
 llvm/test/CodeGen/X86/branch-on-zero.ll | 261 +++++++++++-------------
 1 file changed, 116 insertions(+), 145 deletions(-)

diff --git a/llvm/test/CodeGen/X86/branch-on-zero.ll b/llvm/test/CodeGen/X86/branch-on-zero.ll
index 8171d03cf9d13..311ab027993c8 100644
--- a/llvm/test/CodeGen/X86/branch-on-zero.ll
+++ b/llvm/test/CodeGen/X86/branch-on-zero.ll
@@ -5,26 +5,24 @@
 define i32 @lshr3_then(i32 %a) {
 ; CHECK64-LABEL: lshr3_then:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $7, %edi
-; CHECK64-NEXT:    ja .LBB0_2
-; CHECK64-NEXT:  # %bb.1: # %then
-; CHECK64-NEXT:    xorl %eax, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB0_2: # %else
 ; CHECK64-NEXT:    shrl $3, %edi
+; CHECK64-NEXT:    je .LBB0_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    movl %edi, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB0_1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: lshr3_then:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $7, %eax
-; CHECK32-NEXT:    ja .LBB0_2
-; CHECK32-NEXT:  # %bb.1: # %then
-; CHECK32-NEXT:    xorl %eax, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB0_2: # %else
 ; CHECK32-NEXT:    shrl $3, %eax
+; CHECK32-NEXT:    je .LBB0_1
+; CHECK32-NEXT:  # %bb.2: # %else
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB0_1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 8
@@ -41,27 +39,25 @@ else:
 define i32 @lshr5_else(i32 %a) {
 ; CHECK64-LABEL: lshr5_else:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $31, %edi
-; CHECK64-NEXT:    ja .LBB1_2
-; CHECK64-NEXT:  # %bb.1: # %then
 ; CHECK64-NEXT:    shrl $5, %edi
-; CHECK64-NEXT:    movl %edi, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB1_2: # %else
+; CHECK64-NEXT:    je .LBB1_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    xorl %eax, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB1_1: # %then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: lshr5_else:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $31, %eax
-; CHECK32-NEXT:    ja .LBB1_2
-; CHECK32-NEXT:  # %bb.1: # %then
 ; CHECK32-NEXT:    shrl $5, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB1_2: # %else
+; CHECK32-NEXT:    je .LBB1_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB1_1: # %then
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 32
   br i1 %c, label %then, label %else
@@ -77,27 +73,25 @@ else:
 define i32 @lshr2_entry(i32 %a) {
 ; CHECK64-LABEL: lshr2_entry:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $1, %edi
-; CHECK64-NEXT:    ja .LBB2_2
-; CHECK64-NEXT:  # %bb.1: # %then
 ; CHECK64-NEXT:    shrl %edi
-; CHECK64-NEXT:    movl %edi, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB2_2: # %else
+; CHECK64-NEXT:    je .LBB2_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    xorl %eax, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB2_1: # %then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: lshr2_entry:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $1, %eax
-; CHECK32-NEXT:    ja .LBB2_2
-; CHECK32-NEXT:  # %bb.1: # %then
 ; CHECK32-NEXT:    shrl %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB2_2: # %else
+; CHECK32-NEXT:    je .LBB2_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB2_1: # %then
+; CHECK32-NEXT:    retl
 entry:
   %l = lshr i32 %a, 1
   %c = icmp ult i32 %a, 2
@@ -149,27 +143,25 @@ else:
 define i32 @ashr5_else(i32 %a) {
 ; CHECK64-LABEL: ashr5_else:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $31, %edi
-; CHECK64-NEXT:    ja .LBB4_2
-; CHECK64-NEXT:  # %bb.1: # %then
 ; CHECK64-NEXT:    sarl $5, %edi
-; CHECK64-NEXT:    movl %edi, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB4_2: # %else
+; CHECK64-NEXT:    je .LBB4_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    xorl %eax, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB4_1: # %then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: ashr5_else:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $31, %eax
-; CHECK32-NEXT:    ja .LBB4_2
-; CHECK32-NEXT:  # %bb.1: # %then
 ; CHECK32-NEXT:    sarl $5, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB4_2: # %else
+; CHECK32-NEXT:    je .LBB4_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB4_1: # %then
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp ult i32 %a, 32
   br i1 %c, label %then, label %else
@@ -221,27 +213,25 @@ else:
 define i32 @addm10_then(i32 %a) {
 ; CHECK64-LABEL: addm10_then:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $10, %edi
-; CHECK64-NEXT:    jne .LBB6_2
-; CHECK64-NEXT:  # %bb.1: # %then
 ; CHECK64-NEXT:    addl $-10, %edi
-; CHECK64-NEXT:    movl %edi, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB6_2: # %else
+; CHECK64-NEXT:    je .LBB6_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    xorl %eax, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB6_1: # %then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: addm10_then:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $10, %eax
-; CHECK32-NEXT:    jne .LBB6_2
-; CHECK32-NEXT:  # %bb.1: # %then
 ; CHECK32-NEXT:    addl $-10, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB6_2: # %else
+; CHECK32-NEXT:    je .LBB6_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB6_1: # %then
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
   br i1 %c, label %then, label %else
@@ -293,26 +283,24 @@ else:
 define i32 @sub10_else(i32 %a) {
 ; CHECK64-LABEL: sub10_else:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $10, %edi
-; CHECK64-NEXT:    jne .LBB8_2
-; CHECK64-NEXT:  # %bb.1: # %then
-; CHECK64-NEXT:    xorl %eax, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB8_2: # %else
 ; CHECK64-NEXT:    addl $-10, %edi
+; CHECK64-NEXT:    je .LBB8_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    movl %edi, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB8_1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: sub10_else:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $10, %eax
-; CHECK32-NEXT:    jne .LBB8_2
-; CHECK32-NEXT:  # %bb.1: # %then
-; CHECK32-NEXT:    xorl %eax, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB8_2: # %else
 ; CHECK32-NEXT:    addl $-10, %eax
+; CHECK32-NEXT:    je .LBB8_1
+; CHECK32-NEXT:  # %bb.2: # %else
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB8_1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
@@ -329,26 +317,24 @@ else:
 define i32 @sub10_else_drop_nuw(i32 %a) {
 ; CHECK64-LABEL: sub10_else_drop_nuw:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $10, %edi
-; CHECK64-NEXT:    jne .LBB9_2
-; CHECK64-NEXT:  # %bb.1: # %then
-; CHECK64-NEXT:    xorl %eax, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB9_2: # %else
 ; CHECK64-NEXT:    addl $-10, %edi
+; CHECK64-NEXT:    je .LBB9_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    movl %edi, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB9_1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: sub10_else_drop_nuw:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $10, %eax
-; CHECK32-NEXT:    jne .LBB9_2
-; CHECK32-NEXT:  # %bb.1: # %then
-; CHECK32-NEXT:    xorl %eax, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB9_2: # %else
 ; CHECK32-NEXT:    addl $-10, %eax
+; CHECK32-NEXT:    je .LBB9_1
+; CHECK32-NEXT:  # %bb.2: # %else
+; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB9_1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, 10
@@ -365,27 +351,25 @@ else:
 define i32 @subm10_then(i32 %a) {
 ; CHECK64-LABEL: subm10_then:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $-10, %edi
-; CHECK64-NEXT:    jne .LBB10_2
-; CHECK64-NEXT:  # %bb.1: # %then
 ; CHECK64-NEXT:    addl $10, %edi
-; CHECK64-NEXT:    movl %edi, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB10_2: # %else
+; CHECK64-NEXT:    je .LBB10_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    xorl %eax, %eax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB10_1: # %then
+; CHECK64-NEXT:    movl %edi, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: subm10_then:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $-10, %eax
-; CHECK32-NEXT:    jne .LBB10_2
-; CHECK32-NEXT:  # %bb.1: # %then
 ; CHECK32-NEXT:    addl $10, %eax
-; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB10_2: # %else
+; CHECK32-NEXT:    je .LBB10_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    retl
+; CHECK32-NEXT:  .LBB10_1: # %then
+; CHECK32-NEXT:    retl
 entry:
   %c = icmp eq i32 %a, -10
   br i1 %c, label %then, label %else
@@ -402,25 +386,24 @@ define i64 @lshr64(i64 %a) {
 ; CHECK64-LABEL: lshr64:
 ; CHECK64:       # %bb.0: # %entry
 ; CHECK64-NEXT:    shrq $40, %rdi
-; CHECK64-NEXT:    jne .LBB11_2
-; CHECK64-NEXT:  # %bb.1: # %then
-; CHECK64-NEXT:    xorl %eax, %eax
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB11_2: # %else
+; CHECK64-NEXT:    je .LBB11_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    movq %rdi, %rax
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB11_1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: lshr64:
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    testl $-256, %eax
-; CHECK32-NEXT:    jne .LBB11_2
-; CHECK32-NEXT:  # %bb.1: # %then
-; CHECK32-NEXT:    xorl %eax, %eax
+; CHECK32-NEXT:    shrl $8, %eax
+; CHECK32-NEXT:    je .LBB11_1
+; CHECK32-NEXT:  # %bb.2: # %else
 ; CHECK32-NEXT:    xorl %edx, %edx
 ; CHECK32-NEXT:    retl
-; CHECK32-NEXT:  .LBB11_2: # %else
-; CHECK32-NEXT:    shrl $8, %eax
+; CHECK32-NEXT:  .LBB11_1: # %then
+; CHECK32-NEXT:    xorl %eax, %eax
 ; CHECK32-NEXT:    xorl %edx, %edx
 ; CHECK32-NEXT:    retl
 entry:
@@ -438,55 +421,47 @@ else:
 define i128 @lshr128(i128 %a) {
 ; CHECK64-LABEL: lshr128:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpq $1, %rsi
-; CHECK64-NEXT:    ja .LBB12_2
-; CHECK64-NEXT:  # %bb.1: # %then
-; CHECK64-NEXT:    xorl %eax, %eax
-; CHECK64-NEXT:    xorl %edx, %edx
-; CHECK64-NEXT:    retq
-; CHECK64-NEXT:  .LBB12_2: # %else
 ; CHECK64-NEXT:    shrq %rsi
+; CHECK64-NEXT:    je .LBB12_1
+; CHECK64-NEXT:  # %bb.2: # %else
 ; CHECK64-NEXT:    movq %rsi, %rax
 ; CHECK64-NEXT:    xorl %edx, %edx
 ; CHECK64-NEXT:    retq
+; CHECK64-NEXT:  .LBB12_1: # %then
+; CHECK64-NEXT:    xorl %eax, %eax
+; CHECK64-NEXT:    xorl %edx, %edx
+; CHECK64-NEXT:    retq
 ;
 ; CHECK32-LABEL: lshr128:
 ; CHECK32:       # %bb.0: # %entry
-; CHECK32-NEXT:    pushl %edi
-; CHECK32-NEXT:    .cfi_def_cfa_offset 8
 ; CHECK32-NEXT:    pushl %esi
-; CHECK32-NEXT:    .cfi_def_cfa_offset 12
-; CHECK32-NEXT:    pushl %eax
+; CHECK32-NEXT:    .cfi_def_cfa_offset 8
+; CHECK32-NEXT:    subl $8, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 16
-; CHECK32-NEXT:    .cfi_offset %esi, -12
-; CHECK32-NEXT:    .cfi_offset %edi, -8
+; CHECK32-NEXT:    .cfi_offset %esi, -8
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; CHECK32-NEXT:    xorl %esi, %esi
-; CHECK32-NEXT:    movl $1, %edi
-; CHECK32-NEXT:    cmpl %ecx, %edi
-; CHECK32-NEXT:    sbbl %edx, %esi
-; CHECK32-NEXT:    jb .LBB12_3
-; CHECK32-NEXT:  # %bb.1: # %then
-; CHECK32-NEXT:    movl $0, 12(%eax)
-; CHECK32-NEXT:    movl $0, 8(%eax)
-; CHECK32-NEXT:    movl $0, 4(%eax)
-; CHECK32-NEXT:    movl $0, (%eax)
-; CHECK32-NEXT:    jmp .LBB12_2
-; CHECK32-NEXT:  .LBB12_3: # %else
+; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; CHECK32-NEXT:    shrdl $1, %edx, %ecx
 ; CHECK32-NEXT:    shrl %edx
-; CHECK32-NEXT:    movl %edx, 4(%eax)
+; CHECK32-NEXT:    movl %ecx, %esi
+; CHECK32-NEXT:    orl %edx, %esi
+; CHECK32-NEXT:    je .LBB12_1
+; CHECK32-NEXT:  # %bb.3: # %else
 ; CHECK32-NEXT:    movl %ecx, (%eax)
+; CHECK32-NEXT:    movl %edx, 4(%eax)
+; CHECK32-NEXT:    movl $0, 12(%eax)
+; CHECK32-NEXT:    movl $0, 8(%eax)
+; CHECK32-NEXT:    jmp .LBB12_2
+; CHECK32-NEXT:  .LBB12_1: # %then
 ; CHECK32-NEXT:    movl $0, 12(%eax)
 ; CHECK32-NEXT:    movl $0, 8(%eax)
+; CHECK32-NEXT:    movl $0, 4(%eax)
+; CHECK32-NEXT:    movl $0, (%eax)
 ; CHECK32-NEXT:  .LBB12_2: # %then
-; CHECK32-NEXT:    addl $4, %esp
-; CHECK32-NEXT:    .cfi_def_cfa_offset 12
-; CHECK32-NEXT:    popl %esi
+; CHECK32-NEXT:    addl $8, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 8
-; CHECK32-NEXT:    popl %edi
+; CHECK32-NEXT:    popl %esi
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK32-NEXT:    retl $4
 entry:
@@ -550,11 +525,10 @@ else:
 define i32 @xor_branch_imm_ret(i32 %x) {
 ; CHECK64-LABEL: xor_branch_imm_ret:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $-1365, %edi # imm = 0xFAAB
-; CHECK64-NEXT:    je .LBB14_2
-; CHECK64-NEXT:  # %bb.1: # %if.then
 ; CHECK64-NEXT:    movl %edi, %eax
 ; CHECK64-NEXT:    xorl $-1365, %eax # imm = 0xFAAB
+; CHECK64-NEXT:    je .LBB14_2
+; CHECK64-NEXT:  # %bb.1: # %if.then
 ; CHECK64-NEXT:    retq
 ; CHECK64-NEXT:  .LBB14_2: # %if.end
 ; CHECK64-NEXT:    pushq %rax
@@ -565,11 +539,10 @@ define i32 @xor_branch_imm_ret(i32 %x) {
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    subl $12, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 16
-; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $-1365, %eax # imm = 0xFAAB
+; CHECK32-NEXT:    movl $-1365, %eax # imm = 0xFAAB
+; CHECK32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
 ; CHECK32-NEXT:    je .LBB14_2
 ; CHECK32-NEXT:  # %bb.1: # %if.then
-; CHECK32-NEXT:    xorl $-1365, %eax # imm = 0xFAAB
 ; CHECK32-NEXT:    addl $12, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK32-NEXT:    retl
@@ -590,11 +563,10 @@ if.end:
 define i32 @xor_branch_ret(i32 %x) {
 ; CHECK64-LABEL: xor_branch_ret:
 ; CHECK64:       # %bb.0: # %entry
-; CHECK64-NEXT:    cmpl $2048, %edi # imm = 0x800
-; CHECK64-NEXT:    je .LBB15_2
-; CHECK64-NEXT:  # %bb.1: # %if.then
 ; CHECK64-NEXT:    movl %edi, %eax
 ; CHECK64-NEXT:    xorl $2048, %eax # imm = 0x800
+; CHECK64-NEXT:    je .LBB15_2
+; CHECK64-NEXT:  # %bb.1: # %if.then
 ; CHECK64-NEXT:    retq
 ; CHECK64-NEXT:  .LBB15_2: # %if.end
 ; CHECK64-NEXT:    pushq %rax
@@ -605,11 +577,10 @@ define i32 @xor_branch_ret(i32 %x) {
 ; CHECK32:       # %bb.0: # %entry
 ; CHECK32-NEXT:    subl $12, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 16
-; CHECK32-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; CHECK32-NEXT:    cmpl $2048, %eax # imm = 0x800
+; CHECK32-NEXT:    movl $2048, %eax # imm = 0x800
+; CHECK32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
 ; CHECK32-NEXT:    je .LBB15_2
 ; CHECK32-NEXT:  # %bb.1: # %if.then
-; CHECK32-NEXT:    xorl $2048, %eax # imm = 0x800
 ; CHECK32-NEXT:    addl $12, %esp
 ; CHECK32-NEXT:    .cfi_def_cfa_offset 4
 ; CHECK32-NEXT:    retl



More information about the llvm-commits mailing list