Hans Wennborg | a468601 | 2017-02-16 00:04:05 +0000 | [diff] [blame] | 1 | ; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32 |
| 2 | ; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64 |
| 3 | |
| 4 | declare void @foo() |
| 5 | declare void @bar() |
| 6 | |
| 7 | define void @f(i32 %x, i32 %y) optsize { |
| 8 | entry: |
| 9 | %p = icmp eq i32 %x, %y |
| 10 | br i1 %p, label %bb1, label %bb2 |
| 11 | bb1: |
| 12 | tail call void @foo() |
| 13 | ret void |
| 14 | bb2: |
| 15 | tail call void @bar() |
| 16 | ret void |
| 17 | |
| 18 | ; CHECK-LABEL: f: |
| 19 | ; CHECK: cmp |
| 20 | ; CHECK: jne bar |
| 21 | ; Check that the asm doesn't just look good, but uses the correct encoding. |
| 22 | ; CHECK: encoding: [0x75,A] |
| 23 | ; CHECK: jmp foo |
| 24 | } |
| 25 | |
| 26 | |
| 27 | declare x86_thiscallcc zeroext i1 @baz(i8*, i32) |
| 28 | define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize { |
| 29 | entry: |
| 30 | %and = and i32 %x, 42 |
| 31 | %tobool = icmp eq i32 %and, 0 |
| 32 | br i1 %tobool, label %land.end, label %land.rhs |
| 33 | |
| 34 | land.rhs: |
| 35 | %and6 = and i32 %x, 44 |
| 36 | %tobool7 = icmp eq i32 %and6, 0 |
| 37 | br i1 %tobool7, label %lor.rhs, label %land.end |
| 38 | |
| 39 | lor.rhs: |
| 40 | %call = tail call x86_thiscallcc zeroext i1 @baz(i8* %this, i32 %x) #2 |
| 41 | br label %land.end |
| 42 | |
| 43 | land.end: |
| 44 | %0 = phi i1 [ false, %entry ], [ true, %land.rhs ], [ %call, %lor.rhs ] |
| 45 | ret i1 %0 |
| 46 | |
| 47 | ; Make sure machine block placement isn't confused by the conditional tail call, |
| 48 | ; but sees that it can fall through to the next block. |
| 49 | ; CHECK-LABEL: BlockPlacementTest |
| 50 | ; CHECK: je baz |
| 51 | ; CHECK-NOT: xor |
| 52 | ; CHECK: ret |
| 53 | } |
| 54 | |
| 55 | |
| 56 | |
| 57 | %"class.std::basic_string" = type { %"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" } |
| 58 | %"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* } |
| 59 | declare zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8*, i8*) |
| 60 | |
| 61 | define zeroext i1 @pr31257(%"class.std::basic_string"* nocapture readonly dereferenceable(8) %s) minsize { |
| 62 | ; CHECK-LABEL: pr31257 |
| 63 | entry: |
| 64 | %_M_p.i.i = getelementptr inbounds %"class.std::basic_string", %"class.std::basic_string"* %s, i64 0, i32 0, i32 0 |
| 65 | %0 = load i8*, i8** %_M_p.i.i, align 8 |
| 66 | %arrayidx.i.i.i54 = getelementptr inbounds i8, i8* %0, i64 -24 |
| 67 | %_M_length.i.i55 = bitcast i8* %arrayidx.i.i.i54 to i64* |
| 68 | %1 = load i64, i64* %_M_length.i.i55, align 8 |
| 69 | %add.ptr.i56 = getelementptr inbounds i8, i8* %0, i64 %1 |
| 70 | br label %for.cond |
| 71 | |
| 72 | for.cond: ; preds = %for.inc, %entry |
| 73 | %it.sroa.0.0 = phi i8* [ %0, %entry ], [ %incdec.ptr.i, %for.inc ] |
| 74 | %state.0 = phi i32 [ 0, %entry ], [ %state.1, %for.inc ] |
| 75 | %cmp.i = icmp eq i8* %it.sroa.0.0, %add.ptr.i56 |
| 76 | br i1 %cmp.i, label %5, label %for.body |
| 77 | |
| 78 | for.body: ; preds = %for.cond |
| 79 | switch i32 %state.0, label %for.inc [ |
| 80 | i32 0, label %sw.bb |
| 81 | i32 1, label %sw.bb14 |
| 82 | i32 2, label %sw.bb22 |
| 83 | ] |
| 84 | |
| 85 | sw.bb: ; preds = %for.body |
| 86 | %2 = load i8, i8* %it.sroa.0.0, align 1 |
| 87 | switch i8 %2, label %if.else [ |
| 88 | i8 43, label %for.inc |
| 89 | i8 45, label %for.inc |
| 90 | ] |
| 91 | |
| 92 | if.else: ; preds = %sw.bb |
| 93 | %conv9 = zext i8 %2 to i32 |
| 94 | %isdigittmp45 = add nsw i32 %conv9, -48 |
| 95 | %isdigit46 = icmp ult i32 %isdigittmp45, 10 |
| 96 | br i1 %isdigit46, label %for.inc, label %cleanup.thread.loopexit |
| 97 | |
| 98 | sw.bb14: ; preds = %for.body |
| 99 | %3 = load i8, i8* %it.sroa.0.0, align 1 |
| 100 | %conv16 = zext i8 %3 to i32 |
| 101 | %isdigittmp43 = add nsw i32 %conv16, -48 |
| 102 | %isdigit44 = icmp ult i32 %isdigittmp43, 10 |
| 103 | br i1 %isdigit44, label %for.inc, label %cleanup.thread.loopexit |
| 104 | |
| 105 | sw.bb22: ; preds = %for.body |
| 106 | %4 = load i8, i8* %it.sroa.0.0, align 1 |
| 107 | %conv24 = zext i8 %4 to i32 |
| 108 | %isdigittmp = add nsw i32 %conv24, -48 |
| 109 | %isdigit = icmp ult i32 %isdigittmp, 10 |
| 110 | br i1 %isdigit, label %for.inc, label %if.else28 |
| 111 | |
| 112 | ; Make sure Machine Copy Propagation doesn't delete the mov to %ecx becaue it |
| 113 | ; thinks the conditional tail call clobbers it. |
| 114 | ; CHECK64-LABEL: .LBB2_11: |
| 115 | ; CHECK64: movzbl (%rdi), %ecx |
| 116 | ; CHECK64-NEXT: addl $-48, %ecx |
| 117 | ; CHECK64-NEXT: cmpl $10, %ecx |
| 118 | ; CHECK64-NEXT: movl %r9d, %ecx |
| 119 | ; CHECK64-NEXT: jae _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEE |
| 120 | |
| 121 | if.else28: ; preds = %sw.bb22 |
| 122 | %call34 = tail call zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8* nonnull %it.sroa.0.0, i8* %add.ptr.i56) |
| 123 | br label %cleanup.thread |
| 124 | |
| 125 | for.inc: ; preds = %sw.bb, %sw.bb, %sw.bb22, %sw.bb14, %if.else, %for.body |
| 126 | %state.1 = phi i32 [ %state.0, %for.body ], [ 1, %sw.bb ], [ 2, %if.else ], [ 2, %sw.bb14 ], [ 2, %sw.bb22 ], [ 1, %sw.bb ] |
| 127 | %incdec.ptr.i = getelementptr inbounds i8, i8* %it.sroa.0.0, i64 1 |
| 128 | br label %for.cond |
| 129 | |
| 130 | ; <label>:5: ; preds = %for.cond |
| 131 | %cmp37 = icmp eq i32 %state.0, 2 |
| 132 | br label %cleanup.thread |
| 133 | |
| 134 | cleanup.thread.loopexit: ; preds = %if.else, %sw.bb14 |
| 135 | br label %cleanup.thread |
| 136 | |
| 137 | cleanup.thread: ; preds = %cleanup.thread.loopexit, %if.else28, %5 |
| 138 | %6 = phi i1 [ %cmp37, %5 ], [ %call34, %if.else28 ], [ false, %cleanup.thread.loopexit ] |
| 139 | ret i1 %6 |
| 140 | } |