1 ; RUN: llc -mtriple=aarch64 -verify-machineinstrs < %s | FileCheck --check-prefix=CHECK --check-prefix=OPT %s 2 ; RUN: llc -mtriple=aarch64 -verify-machineinstrs -O0 -fast-isel=0 -global-isel=false < %s | FileCheck --check-prefix=CHECK --check-prefix=NOOPT %s 3 4 declare void @foo() 5 6 ; Check that the inverted or doesn't inhibit the splitting of the 7 ; complex conditional into three branch instructions. 8 ; CHECK-LABEL: test_and_not: 9 ; CHECK: cbz w0, [[L:\.LBB[0-9_]+]] 10 ; OPT: cmp w1, #2 11 ; NOOPT: subs w{{[0-9]+}}, w{{[0-9]+}}, #2 12 ; CHECK: b.lo [[L]] 13 ; OPT: cmp w2, #2 14 ; NOOPT: subs w{{[0-9]+}}, w{{[0-9]+}}, #2 15 ; CHECK: b.hi [[L]] 16 define void @test_and_not(i32 %a, i32 %b, i32 %c) { 17 bb1: 18 %cmp1 = icmp ult i32 %a, 1 19 %cmp2 = icmp ult i32 %b, 2 20 %cmp3 = icmp ult i32 %c, 3 21 %or = or i1 %cmp1, %cmp2 22 %not.or = xor i1 %or, -1 23 %and = and i1 %not.or, %cmp3 24 br i1 %and, label %bb2, label %bb3 25 26 bb2: 27 ret void 28 29 bb3: 30 call void @foo() 31 ret void 32 } 33 34 ; Check that non-canonicalized xor not is handled correctly by FindMergedConditions. 35 ; CHECK-LABEL: test_and_not2: 36 ; CHECK: cbz w0, [[L:\.LBB[0-9_]+]] 37 ; OPT: cmp w1, #2 38 ; NOOPT: subs w{{[0-9]+}}, w{{[0-9]+}}, #2 39 ; CHECK: b.lo [[L]] 40 ; OPT: cmp w2, #2 41 ; NOOPT: subs w{{[0-9]+}}, w{{[0-9]+}}, #2 42 ; CHECK: b.hi [[L]] 43 define void @test_and_not2(i32 %a, i32 %b, i32 %c) { 44 bb1: 45 %cmp1 = icmp ult i32 %a, 1 46 %cmp2 = icmp ult i32 %b, 2 47 %cmp3 = icmp ult i32 %c, 3 48 %or = or i1 %cmp1, %cmp2 49 %not.or = xor i1 -1, %or 50 %and = and i1 %not.or, %cmp3 51 br i1 %and, label %bb2, label %bb3 52 53 bb2: 54 ret void 55 56 bb3: 57 call void @foo() 58 ret void 59 } 60 61 ; Check that cmps in different blocks are handled correctly by FindMergedConditions. 62 ; CHECK-LABEL: test_cmp_other_block: 63 ; OPT: cmp w{{[0-9]+}}, #0 64 ; OPT: b.gt [[L:\.LBB[0-9_]+]] 65 ; OPT: tbz w1, #0, [[L]] 66 ; 67 ; NOOPT: subs w{{[0-9]+}}, w{{[0-9]+}}, #0 68 ; NOOPT: cset [[R1:w[0-9]+]], gt 69 ; NOOPT: str w1, [sp, #[[SLOT2:[0-9]+]]] 70 ; NOOPT: str [[R1]], [sp, #[[SLOT1:[0-9]+]]] 71 ; NOOPT: b .LBB 72 ; NOOPT: ldr [[R2:w[0-9]+]], [sp, #[[SLOT1]]] 73 ; NOOPT: tbnz [[R2]], #0, [[L:\.LBB[0-9_]+]] 74 ; NOOPT: ldr [[R3:w[0-9]+]], [sp, #[[SLOT2]]] 75 ; NOOPT: tbz [[R3]], #0, [[L]] 76 define void @test_cmp_other_block(i32* %p, i1 %c) { 77 entry: 78 %l = load i32, i32* %p 79 %cmp = icmp sgt i32 %l, 0 80 br label %bb1 81 82 bb1: 83 %cmp.i = xor i1 %cmp, true 84 %or.cond1.i = and i1 %cmp.i, %c 85 br i1 %or.cond1.i, label %bb2, label %bb3 86 87 bb2: 88 ret void 89 90 bb3: 91 call void @foo() 92 ret void 93 } 94 95