; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 ; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -O2 | FileCheck %s ; Test implementation of combining br_ccmask for flag output operand, and ; optimizing ipm sequence using conditional branches. declare void @dummy() ; Check a case where the cc is used as an integer. ; Just (srl (ipm)) sequence without optimization. define i32 @test(ptr %a) { ; CHECK-LABEL: test: ; CHECK: # %bb.0: ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: ipm %r2 ; CHECK-NEXT: srl %r2, 28 ; CHECK-NEXT: br %r14 %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) ret i32 %cc } ; Test-1(f1_0_*). Test all 14 valid combinations, where cc is being used for ; branching. ; Check (cc == 0). define void @f1_0_eq_0(ptr %a) { ; CHECK-LABEL: f1_0_eq_0: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jge dummy@PLT ; CHECK-NEXT: .LBB1_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp eq i32 %cc, 0 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc != 0). define void @f1_0_ne_0(ptr %a) { ; CHECK-LABEL: f1_0_ne_0: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgne dummy@PLT ; CHECK-NEXT: .LBB2_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ugt i32 %cc, 0 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 1). define void @f1_0_eq_1(ptr %a) { ; CHECK-LABEL: f1_0_eq_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgl dummy@PLT ; CHECK-NEXT: .LBB3_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp eq i32 %cc, 1 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc != 1). define void @f1_0_ne_1(ptr %a) { ; CHECK-LABEL: f1_0_ne_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnl dummy@PLT ; CHECK-NEXT: .LBB4_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ne i32 %cc, 1 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 2). define void @f1_0_eq_2(ptr %a) { ; CHECK-LABEL: f1_0_eq_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgh dummy@PLT ; CHECK-NEXT: .LBB5_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp eq i32 %cc, 2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc != 2). define void @f1_0_ne_2(ptr %a) { ; CHECK-LABEL: f1_0_ne_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnh dummy@PLT ; CHECK-NEXT: .LBB6_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ne i32 %cc, 2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 3). define void @f1_0_eq_3(ptr %a) { ; CHECK-LABEL: f1_0_eq_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgo dummy@PLT ; CHECK-NEXT: .LBB7_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp eq i32 %cc, 3 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc != 3). define void @f1_0_ne_3(ptr %a) { ; CHECK-LABEL: f1_0_ne_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgno dummy@PLT ; CHECK-NEXT: .LBB8_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ult i32 %cc, 3 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 0|1). define void @f1_0_01(ptr %a) { ; CHECK-LABEL: f1_0_01: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgle dummy@PLT ; CHECK-NEXT: .LBB9_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ult i32 %cc, 2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 0|2). define void @f1_0_02(ptr %a) { ; CHECK-LABEL: f1_0_02: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jghe dummy@PLT ; CHECK-NEXT: .LBB10_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %and = and i32 %cc, 1 %cmp = icmp eq i32 %and, 0 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 0|3). define void @f1_0_03(ptr %a) { ; CHECK-LABEL: f1_0_03: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnlh dummy@PLT ; CHECK-NEXT: .LBB11_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp0 = icmp ne i32 %cc, 0 %cmp3 = icmp ne i32 %cc, 3 %cmp.inv = and i1 %cmp0, %cmp3 br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 1|2). define void @f1_0_12(ptr %a) { ; CHECK-LABEL: f1_0_12: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jglh dummy@PLT ; CHECK-NEXT: .LBB12_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmpeq1 = icmp eq i32 %cc, 1 %cmpeq2 = icmp eq i32 %cc, 2 %cmp = or i1 %cmpeq1, %cmpeq2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 1|3). define void @f1_0_13(ptr %a) { ; CHECK-LABEL: f1_0_13: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnhe dummy@PLT ; CHECK-NEXT: .LBB13_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmpeq1 = icmp eq i32 %cc, 1 %cmpeq3 = icmp eq i32 %cc, 3 %cmp = or i1 %cmpeq1, %cmpeq3 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check (cc == 2|3). define void @f1_0_23(ptr %a) { ; CHECK-LABEL: f1_0_23: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnle dummy@PLT ; CHECK-NEXT: .LBB14_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmp = icmp ugt i32 %cc, 1 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Test-2(f1_1_*/f1_2_*/fl_3_*/f1_4_*). ; Test Mixed patterns involving Binary Ops. ; Check 'add' for (cc != 0). define void @f1_1_1(ptr %a) { ; CHECK-LABEL: f1_1_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgne dummy@PLT ; CHECK-NEXT: .LBB15_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %add = add nsw i32 %cc, -1 %cmp = icmp ult i32 %add, 3 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'add' for (cc == 1|2). define void @f1_1_2(ptr %a) { ; CHECK-LABEL: f1_1_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jglh dummy@PLT ; CHECK-NEXT: .LBB16_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %add = add nsw i32 %cc, -1 %cmp = icmp ult i32 %add, 2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'add' for (cc == 1|2). define void @f1_1_3(ptr %a) { ; CHECK-LABEL: f1_1_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jglh dummy@PLT ; CHECK-NEXT: .LBB17_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %add = add nsw i32 %cc, -3 %cmp.inv = icmp ult i32 %add, -2 br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'and' with one operand cc and other select_ccmask(cc !=1). define void @f1_2_1(ptr %a) { ; CHECK-LABEL: f1_2_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnl dummy@PLT ; CHECK-NEXT: .LBB18_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %andcc = and i32 %cc, 1 %cmpne0 = icmp ne i32 %andcc, 0 %cmpne3 = icmp ne i32 %cc, 3 %cmp.inv = and i1 %cmpne3, %cmpne0 br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'and' with both operands select_ccmask(cc != 2). define void @f1_2_2(ptr %a) { ; CHECK-LABEL: f1_2_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnh dummy@PLT ; CHECK-NEXT: .LBB19_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %ugt1 = icmp samesign ugt i32 %cc, 1 %cmpne3 = icmp ne i32 %cc, 3 %and.cond.inv = and i1 %ugt1, %cmpne3 br i1 %and.cond.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'and/tm' for (cc == 0|2). define void @f1_2_3(ptr %a) { ; CHECK-LABEL: f1_2_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jghe dummy@PLT ; CHECK-NEXT: .LBB20_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %and = and i32 %cc, 1 %cmp = icmp eq i32 %and, 0 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'and/tm' for (cc == 1|3). define void @f1_2_4(ptr %a) { ; CHECK-LABEL: f1_2_4: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnhe dummy@PLT ; CHECK-NEXT: .LBB21_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %and = and i32 %cc, 1 %cmp = icmp eq i32 %and, 0 br i1 %cmp, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'icmp' with one operand 'and' and other 'select_ccmask'(cc != 1). define void @f1_2_5(ptr %a) { ; CHECK-LABEL: f1_2_5: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnl dummy@PLT ; CHECK-NEXT: .LBB22_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %trunc = trunc i32 %cc to i1 %cmpne3 = icmp ne i32 %cc, 3 %cmp = xor i1 %cmpne3, %trunc br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void } ; Check nested 'xor' cc with select_ccmask(cc != 1). define void @f1_3_1(ptr %a) { ; CHECK-LABEL: f1_3_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnl dummy@PLT ; CHECK-NEXT: .LBB23_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %cmpeq0 = icmp eq i32 %cc, 0 %cmpeq2 = icmp eq i32 %cc, 2 %xor = xor i1 %cmpeq0, %cmpeq2 %cmpne3 = icmp ne i32 %cc, 3 %cmp.inv = xor i1 %cmpne3, %xor br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check branching on 'tm' and 'xor' with one operand cc and the other ; select_ccmask(cc !=1). define void @f1_3_2(ptr %a) { ; CHECK-LABEL: f1_3_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnl dummy@PLT ; CHECK-NEXT: .LBB24_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %trunc = trunc i32 %cc to i1 %cmpeq3 = icmp eq i32 %cc, 3 %cmp.inv = xor i1 %cmpeq3, %trunc br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check branching on 'tm' and 'xor' with one operand cc and the other ; select_ccmask(cc !=2). define void @f1_3_3(ptr %a) { ; CHECK-LABEL: f1_3_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgnh dummy@PLT ; CHECK-NEXT: .LBB25_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %trunc = trunc i32 %cc to i1 %cmpne0 = icmp ne i32 %cc, 0 %cmp.cond.inv = xor i1 %cmpne0, %trunc br i1 %cmp.cond.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'or' with both operands are select_ccmask one with TM and other with ; ICMP(cc == 1). define void @f1_4_1(ptr %a) { ; CHECK-LABEL: f1_4_1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgl dummy@PLT ; CHECK-NEXT: .LBB26_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %andcc = and i32 %cc, 1 %cmpeq0 = icmp eq i32 %andcc, 0 %cmpeq3 = icmp eq i32 %cc, 3 %cmp.cond.inv = or i1 %cmpeq3, %cmpeq0 br i1 %cmp.cond.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'or' for (cc == 0|1). define void @f1_4_2(ptr %a) { ; CHECK-LABEL: f1_4_2: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgle dummy@PLT ; CHECK-NEXT: .LBB27_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %or = or disjoint i32 %cc, -4 %cmp.inv = icmp samesign ugt i32 %or, -3 br i1 %cmp.inv, label %exit, label %branch branch: tail call void @dummy() br label %exit exit: ret void } ; Check 'or' for (cc == 0|1). define void @f1_4_3(ptr %a) { ; CHECK-LABEL: f1_4_3: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: #APP ; CHECK-NEXT: alsi 0(%r2), -1 ; CHECK-EMPTY: ; CHECK-NEXT: #NO_APP ; CHECK-NEXT: jgle dummy@PLT ; CHECK-NEXT: .LBB28_1: # %exit ; CHECK-NEXT: br %r14 entry: %cc = tail call i32 asm sideeffect "alsi $1,-1\0A", "={@cc},=*QS,*QS,~{memory}"(ptr elementtype(i32) %a, ptr elementtype(i32) %a) %tmp = icmp ult i32 %cc, 4 tail call void @llvm.assume(i1 %tmp) %or = or disjoint i32 %cc, -4 %cmp = icmp samesign ult i32 %or, -2 br i1 %cmp, label %branch, label %exit branch: tail call void @dummy() br label %exit exit: ret void }