1 ; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s 2 ; RUN: llc -verify-machineinstrs -print-before=peephole-opt -print-after=peephole-opt -mtriple=powerpc64le-unknown-linux-gnu -o /dev/null 2>&1 < %s | FileCheck %s 3 4 ; CHECK-LABEL: fn1 5 define signext i32 @fn1(i32 %baz) { 6 %1 = mul nsw i32 %baz, 208 7 %2 = zext i32 %1 to i64 8 %3 = shl i64 %2, 48 9 %4 = ashr exact i64 %3, 48 10 ; CHECK: ANDIo8 killed {{[^,]+}}, 65520, implicit-def dead $cr0 11 ; CHECK: CMPLDI 12 ; CHECK: BCC 13 14 ; CHECK: ANDIo8 {{[^,]+}}, 65520, implicit-def $cr0 15 ; CHECK: COPY $cr0 16 ; CHECK: BCC 17 %5 = icmp eq i64 %4, 0 18 br i1 %5, label %foo, label %bar 19 20 foo: 21 ret i32 1 22 23 bar: 24 ret i32 0 25 } 26 27 ; CHECK-LABEL: fn2 28 define signext i32 @fn2(i64 %a, i64 %b) { 29 ; CHECK: OR8o {{[^, ]+}}, {{[^, ]+}}, implicit-def $cr0 30 ; CHECK: [[CREG:[^, ]+]]:crrc = COPY killed $cr 31 ; CHECK: BCC 12, killed [[CREG]] 32 %1 = or i64 %b, %a 33 %2 = icmp sgt i64 %1, -1 34 br i1 %2, label %foo, label %bar 35 36 foo: 37 ret i32 1 38 39 bar: 40 ret i32 0 41 } 42 43 ; CHECK-LABEL: fn3 44 define signext i32 @fn3(i32 %a) { 45 ; CHECK: ANDIo killed {{[%0-9]+}}{{[^,]*}}, 10, implicit-def $cr0 46 ; CHECK: [[CREG:[^, ]+]]:crrc = COPY $cr0 47 ; CHECK: BCC 76, killed [[CREG]] 48 %1 = and i32 %a, 10 49 %2 = icmp ne i32 %1, 0 50 br i1 %2, label %foo, label %bar 51 52 foo: 53 ret i32 1 54 55 bar: 56 ret i32 0 57 } 58 59 ; This test case confirms that a record-form instruction is 60 ; generated even if the branch has a static branch hint. 61 62 ; CHECK-LABEL: fn4 63 define i64 @fn4(i64 %a, i64 %b) { 64 ; CHECK: ADD8o 65 ; CHECK-NOT: CMP 66 ; CHECK: BCC 71 67 68 entry: 69 %add = add nsw i64 %b, %a 70 %cmp = icmp eq i64 %add, 0 71 br i1 %cmp, label %if.then, label %if.end 72 73 if.then: 74 tail call void @exit(i32 signext 0) #3 75 unreachable 76 77 if.end: 78 ret i64 %add 79 } 80 81 declare void @exit(i32 signext) 82 83 ; Since %v1 and %v2 are zero-extended 32-bit values, %1 is also zero-extended. 84 ; In this case, we want to use ORo instead of OR + CMPLWI. 85 86 ; CHECK-LABEL: fn5 87 define zeroext i32 @fn5(i32* %p1, i32* %p2) { 88 ; CHECK: ORo 89 ; CHECK-NOT: CMP 90 ; CHECK: BCC 91 %v1 = load i32, i32* %p1 92 %v2 = load i32, i32* %p2 93 %1 = or i32 %v1, %v2 94 %2 = icmp eq i32 %1, 0 95 br i1 %2, label %foo, label %bar 96 97 foo: 98 ret i32 1 99 100 bar: 101 ret i32 0 102 } 103 104 ; This test confirms record-form instructions are emitted for comparison 105 ; against a non-zero value. 106 107 ; CHECK-LABEL: fn6 108 define i8* @fn6(i8* readonly %p) { 109 ; CHECK: LBZU 110 ; CHECK: EXTSBo 111 ; CHECK-NOT: CMP 112 ; CHECK: BCC 113 ; CHECK: LBZU 114 ; CHECK: EXTSBo 115 ; CHECK-NOT: CMP 116 ; CHECK: BCC 117 118 entry: 119 %incdec.ptr = getelementptr inbounds i8, i8* %p, i64 -1 120 %0 = load i8, i8* %incdec.ptr 121 %cmp = icmp sgt i8 %0, -1 122 br i1 %cmp, label %out, label %if.end 123 124 if.end: 125 %incdec.ptr2 = getelementptr inbounds i8, i8* %p, i64 -2 126 %1 = load i8, i8* %incdec.ptr2 127 %cmp4 = icmp sgt i8 %1, -1 128 br i1 %cmp4, label %out, label %cleanup 129 130 out: 131 %p.addr.0 = phi i8* [ %incdec.ptr, %entry ], [ %incdec.ptr2, %if.end ] 132 br label %cleanup 133 134 cleanup: 135 %retval.0 = phi i8* [ %p.addr.0, %out ], [ null, %if.end ] 136 ret i8* %retval.0 137 } 138