| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -O2 | FileCheck %s |
| |
| ; Test for issue #160612: OR conditions in branches should use multiple branches |
| ; instead of materializing booleans with SETCC when no special optimizations apply. |
| |
| declare void @subroutine_foo() |
| declare void @subroutine_bar() |
| |
| ; Original issue: (x == 0 || y == 0) was generating SETCC + TEST + BRANCH |
| ; instead of using two conditional branches directly. |
| define void @func_a(i32 noundef %x, i32 noundef %y) { |
| ; CHECK-LABEL: func_a: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: testl %edi, %edi |
| ; CHECK-NEXT: je subroutine_foo@PLT # TAILCALL |
| ; CHECK-NEXT: # %bb.1: # %entry |
| ; CHECK-NEXT: testl %esi, %esi |
| ; CHECK-NEXT: jne subroutine_bar@PLT # TAILCALL |
| ; CHECK-NEXT: # %bb.2: # %if.then |
| ; CHECK-NEXT: jmp subroutine_foo@PLT # TAILCALL |
| entry: |
| %cmp = icmp eq i32 %x, 0 |
| %cmp1 = icmp eq i32 %y, 0 |
| %or.cond = or i1 %cmp, %cmp1 |
| br i1 %or.cond, label %if.then, label %if.else |
| |
| if.then: |
| tail call void @subroutine_foo() |
| br label %if.end |
| |
| if.else: |
| tail call void @subroutine_bar() |
| br label %if.end |
| |
| if.end: |
| ret void |
| } |
| |
| ; Reference implementation that already generated optimal code. |
| ; This should continue to generate the same optimal code. |
| define void @func_b(i32 noundef %x, i32 noundef %y) { |
| ; CHECK-LABEL: func_b: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: testl %edi, %edi |
| ; CHECK-NEXT: je subroutine_foo@PLT # TAILCALL |
| ; CHECK-NEXT: # %bb.1: # %if.else |
| ; CHECK-NEXT: testl %esi, %esi |
| ; CHECK-NEXT: je subroutine_foo@PLT # TAILCALL |
| ; CHECK-NEXT: # %bb.2: # %if.else3 |
| ; CHECK-NEXT: jmp subroutine_bar@PLT # TAILCALL |
| entry: |
| %cmp = icmp eq i32 %x, 0 |
| br i1 %cmp, label %if.then, label %if.else |
| |
| if.then: |
| tail call void @subroutine_foo() |
| br label %if.end4 |
| |
| if.else: |
| %cmp1 = icmp eq i32 %y, 0 |
| br i1 %cmp1, label %if.then2, label %if.else3 |
| |
| if.then2: |
| tail call void @subroutine_foo() |
| br label %if.end4 |
| |
| if.else3: |
| tail call void @subroutine_bar() |
| br label %if.end4 |
| |
| if.end4: |
| ret void |
| } |