diff options
author | Hans Wennborg <hans@hanshq.net> | 2017-02-16 00:04:05 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2017-02-16 00:04:05 +0000 |
commit | a468601e0eadd6b4cc5d56e5aa729320a296fa46 (patch) | |
tree | 65eb408e24d23a40aa0865d36f7cd0b3fdcff5c5 /llvm/test/CodeGen/X86/conditional-tailcall.ll | |
parent | d77a6730b181d6eea672c30e3a736c1281a9a3f0 (diff) | |
download | bcm5719-llvm-a468601e0eadd6b4cc5d56e5aa729320a296fa46.tar.gz bcm5719-llvm-a468601e0eadd6b4cc5d56e5aa729320a296fa46.zip |
[X86] Re-enable conditional tail calls and fix PR31257.
This reverts r294348, which removed support for conditional tail calls
due to the PR above. It fixes the PR by marking live registers as
implicitly used and defined by the now predicated tailcall. This is
similar to how IfConversion predicates instructions.
Differential Revision: https://reviews.llvm.org/D29856
llvm-svn: 295262
Diffstat (limited to 'llvm/test/CodeGen/X86/conditional-tailcall.ll')
-rw-r--r-- | llvm/test/CodeGen/X86/conditional-tailcall.ll | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/X86/conditional-tailcall.ll b/llvm/test/CodeGen/X86/conditional-tailcall.ll new file mode 100644 index 00000000000..379a9ad84d5 --- /dev/null +++ b/llvm/test/CodeGen/X86/conditional-tailcall.ll @@ -0,0 +1,140 @@ +; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK32 +; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK64 + +declare void @foo() +declare void @bar() + +define void @f(i32 %x, i32 %y) optsize { +entry: + %p = icmp eq i32 %x, %y + br i1 %p, label %bb1, label %bb2 +bb1: + tail call void @foo() + ret void +bb2: + tail call void @bar() + ret void + +; CHECK-LABEL: f: +; CHECK: cmp +; CHECK: jne bar +; Check that the asm doesn't just look good, but uses the correct encoding. +; CHECK: encoding: [0x75,A] +; CHECK: jmp foo +} + + +declare x86_thiscallcc zeroext i1 @baz(i8*, i32) +define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize { +entry: + %and = and i32 %x, 42 + %tobool = icmp eq i32 %and, 0 + br i1 %tobool, label %land.end, label %land.rhs + +land.rhs: + %and6 = and i32 %x, 44 + %tobool7 = icmp eq i32 %and6, 0 + br i1 %tobool7, label %lor.rhs, label %land.end + +lor.rhs: + %call = tail call x86_thiscallcc zeroext i1 @baz(i8* %this, i32 %x) #2 + br label %land.end + +land.end: + %0 = phi i1 [ false, %entry ], [ true, %land.rhs ], [ %call, %lor.rhs ] + ret i1 %0 + +; Make sure machine block placement isn't confused by the conditional tail call, +; but sees that it can fall through to the next block. +; CHECK-LABEL: BlockPlacementTest +; CHECK: je baz +; CHECK-NOT: xor +; CHECK: ret +} + + + +%"class.std::basic_string" = type { %"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" } +%"struct.std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Alloc_hider" = type { i8* } +declare zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8*, i8*) + +define zeroext i1 @pr31257(%"class.std::basic_string"* nocapture readonly dereferenceable(8) %s) minsize { +; CHECK-LABEL: pr31257 +entry: + %_M_p.i.i = getelementptr inbounds %"class.std::basic_string", %"class.std::basic_string"* %s, i64 0, i32 0, i32 0 + %0 = load i8*, i8** %_M_p.i.i, align 8 + %arrayidx.i.i.i54 = getelementptr inbounds i8, i8* %0, i64 -24 + %_M_length.i.i55 = bitcast i8* %arrayidx.i.i.i54 to i64* + %1 = load i64, i64* %_M_length.i.i55, align 8 + %add.ptr.i56 = getelementptr inbounds i8, i8* %0, i64 %1 + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %it.sroa.0.0 = phi i8* [ %0, %entry ], [ %incdec.ptr.i, %for.inc ] + %state.0 = phi i32 [ 0, %entry ], [ %state.1, %for.inc ] + %cmp.i = icmp eq i8* %it.sroa.0.0, %add.ptr.i56 + br i1 %cmp.i, label %5, label %for.body + +for.body: ; preds = %for.cond + switch i32 %state.0, label %for.inc [ + i32 0, label %sw.bb + i32 1, label %sw.bb14 + i32 2, label %sw.bb22 + ] + +sw.bb: ; preds = %for.body + %2 = load i8, i8* %it.sroa.0.0, align 1 + switch i8 %2, label %if.else [ + i8 43, label %for.inc + i8 45, label %for.inc + ] + +if.else: ; preds = %sw.bb + %conv9 = zext i8 %2 to i32 + %isdigittmp45 = add nsw i32 %conv9, -48 + %isdigit46 = icmp ult i32 %isdigittmp45, 10 + br i1 %isdigit46, label %for.inc, label %cleanup.thread.loopexit + +sw.bb14: ; preds = %for.body + %3 = load i8, i8* %it.sroa.0.0, align 1 + %conv16 = zext i8 %3 to i32 + %isdigittmp43 = add nsw i32 %conv16, -48 + %isdigit44 = icmp ult i32 %isdigittmp43, 10 + br i1 %isdigit44, label %for.inc, label %cleanup.thread.loopexit + +sw.bb22: ; preds = %for.body + %4 = load i8, i8* %it.sroa.0.0, align 1 + %conv24 = zext i8 %4 to i32 + %isdigittmp = add nsw i32 %conv24, -48 + %isdigit = icmp ult i32 %isdigittmp, 10 + br i1 %isdigit, label %for.inc, label %if.else28 + +; Make sure Machine Copy Propagation doesn't delete the mov to %ecx becaue it +; thinks the conditional tail call clobbers it. +; CHECK64-LABEL: .LBB2_11: +; CHECK64: movzbl (%rdi), %ecx +; CHECK64-NEXT: addl $-48, %ecx +; CHECK64-NEXT: cmpl $10, %ecx +; CHECK64-NEXT: movl %r9d, %ecx +; CHECK64-NEXT: jae _Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEE + +if.else28: ; preds = %sw.bb22 + %call34 = tail call zeroext i1 @_Z20isValidIntegerSuffixN9__gnu_cxx17__normal_iteratorIPKcSsEES3_(i8* nonnull %it.sroa.0.0, i8* %add.ptr.i56) + br label %cleanup.thread + +for.inc: ; preds = %sw.bb, %sw.bb, %sw.bb22, %sw.bb14, %if.else, %for.body + %state.1 = phi i32 [ %state.0, %for.body ], [ 1, %sw.bb ], [ 2, %if.else ], [ 2, %sw.bb14 ], [ 2, %sw.bb22 ], [ 1, %sw.bb ] + %incdec.ptr.i = getelementptr inbounds i8, i8* %it.sroa.0.0, i64 1 + br label %for.cond + +; <label>:5: ; preds = %for.cond + %cmp37 = icmp eq i32 %state.0, 2 + br label %cleanup.thread + +cleanup.thread.loopexit: ; preds = %if.else, %sw.bb14 + br label %cleanup.thread + +cleanup.thread: ; preds = %cleanup.thread.loopexit, %if.else28, %5 + %6 = phi i1 [ %cmp37, %5 ], [ %call34, %if.else28 ], [ false, %cleanup.thread.loopexit ] + ret i1 %6 +} |