; 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 }