| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py |
| ; RUN: llc < %s -mtriple=powerpc64le-- -verify-machineinstrs | FileCheck %s |
| ; RUN: llc < %s -mtriple=powerpc64-- -verify-machineinstrs | FileCheck %s \ |
| ; RUN: --check-prefix=BE |
| %struct.__jmp_buf_tag = type { [64 x i64], i32, %struct.__sigset_t, [8 x i8] } |
| %struct.__sigset_t = type { [16 x i64] } |
| |
| @.str = private unnamed_addr constant [33 x i8] c"Successfully returned from main\0A\00", align 1 |
| |
| ; Function Attrs: nounwind |
| define dso_local signext i32 @main(i32 signext %argc, i8** nocapture readnone %argv) local_unnamed_addr #0 { |
| ; CHECK-LABEL: main: |
| ; CHECK: # %bb.0: # %entry |
| ; CHECK-NEXT: mfocrf 12, 32 |
| ; CHECK-NEXT: mflr 0 |
| ; CHECK-NEXT: std 31, -8(1) |
| ; CHECK-NEXT: std 0, 16(1) |
| ; CHECK-NEXT: stw 12, 8(1) |
| ; CHECK-NEXT: stdu 1, -784(1) |
| ; CHECK-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; CHECK-NEXT: cmpwi 2, 3, 2 |
| ; CHECK-NEXT: mr 31, 1 |
| ; CHECK-NEXT: li 3, 0 |
| ; CHECK-NEXT: blt 2, .LBB0_3 |
| ; CHECK-NEXT: # %bb.1: # %if.end |
| ; CHECK-NEXT: addi 3, 31, 112 |
| ; CHECK-NEXT: bl _setjmp |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: crmove 20, 10 |
| ; CHECK-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; CHECK-NEXT: cmpwi 3, 0 |
| ; CHECK-NEXT: crorc 20, 10, 2 |
| ; CHECK-NEXT: crmove 21, 2 |
| ; CHECK-NEXT: bc 4, 20, .LBB0_4 |
| ; CHECK-NEXT: # %bb.2: # %if.end5 |
| ; CHECK-NEXT: addis 3, 2, .L.str@toc@ha |
| ; CHECK-NEXT: addi 3, 3, .L.str@toc@l |
| ; CHECK-NEXT: bl printf |
| ; CHECK-NEXT: nop |
| ; CHECK-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; CHECK-NEXT: .LBB0_3: # %return |
| ; CHECK-NEXT: extsw 3, 3 |
| ; CHECK-NEXT: addi 1, 31, 784 |
| ; CHECK-NEXT: ld 0, 16(1) |
| ; CHECK-NEXT: lwz 12, 8(1) |
| ; CHECK-NEXT: ld 31, -8(1) |
| ; CHECK-NEXT: mtocrf 32, 12 |
| ; CHECK-NEXT: mtlr 0 |
| ; CHECK-NEXT: blr |
| ; CHECK-NEXT: .LBB0_4: # %if.then3 |
| ; CHECK-NEXT: ld 4, 0(1) |
| ; CHECK-NEXT: stdu 4, -16(1) |
| ; CHECK-NEXT: addi 3, 1, 96 |
| ; CHECK-NEXT: li 4, -1 |
| ; CHECK-NEXT: stb 4, 0(3) |
| ; CHECK-NEXT: addi 4, 31, 112 |
| ; CHECK-NEXT: bl test |
| ; CHECK-NEXT: nop |
| ; |
| ; BE-LABEL: main: |
| ; BE: # %bb.0: # %entry |
| ; BE-NEXT: mflr 0 |
| ; BE-NEXT: std 31, -8(1) |
| ; BE-NEXT: std 0, 16(1) |
| ; BE-NEXT: mfcr 12 |
| ; BE-NEXT: stw 12, 8(1) |
| ; BE-NEXT: stdu 1, -800(1) |
| ; BE-NEXT: li 4, 0 |
| ; BE-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; BE-NEXT: cmpwi 2, 3, 2 |
| ; BE-NEXT: mr 3, 4 |
| ; BE-NEXT: mr 31, 1 |
| ; BE-NEXT: blt 2, .LBB0_3 |
| ; BE-NEXT: # %bb.1: # %if.end |
| ; BE-NEXT: addi 3, 31, 128 |
| ; BE-NEXT: bl _setjmp |
| ; BE-NEXT: nop |
| ; BE-NEXT: crmove 20, 10 |
| ; BE-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; BE-NEXT: cmpwi 3, 0 |
| ; BE-NEXT: crorc 20, 10, 2 |
| ; BE-NEXT: crmove 21, 2 |
| ; BE-NEXT: bc 4, 20, .LBB0_4 |
| ; BE-NEXT: # %bb.2: # %if.end5 |
| ; BE-NEXT: addis 3, 2, .L.str@toc@ha |
| ; BE-NEXT: addi 3, 3, .L.str@toc@l |
| ; BE-NEXT: bl printf |
| ; BE-NEXT: nop |
| ; BE-NEXT: # kill: def $r3 killed $r3 killed $x3 |
| ; BE-NEXT: .LBB0_3: # %return |
| ; BE-NEXT: extsw 3, 3 |
| ; BE-NEXT: addi 1, 31, 800 |
| ; BE-NEXT: ld 0, 16(1) |
| ; BE-NEXT: lwz 12, 8(1) |
| ; BE-NEXT: ld 31, -8(1) |
| ; BE-NEXT: mtlr 0 |
| ; BE-NEXT: mtcrf 32, 12 # cr2 |
| ; BE-NEXT: blr |
| ; BE-NEXT: .LBB0_4: # %if.then3 |
| ; BE-NEXT: ld 4, 0(1) |
| ; BE-NEXT: stdu 4, -16(1) |
| ; BE-NEXT: addi 3, 1, 112 |
| ; BE-NEXT: li 4, -1 |
| ; BE-NEXT: stb 4, 0(3) |
| ; BE-NEXT: addi 4, 31, 128 |
| ; BE-NEXT: bl test |
| ; BE-NEXT: nop |
| entry: |
| %env_buffer = alloca [1 x %struct.__jmp_buf_tag], align 16 |
| %cmp = icmp slt i32 %argc, 2 |
| br i1 %cmp, label %return, label %if.end |
| |
| if.end: ; preds = %entry |
| %0 = bitcast [1 x %struct.__jmp_buf_tag]* %env_buffer to i8* |
| call void @llvm.lifetime.start.p0i8(i64 656, i8* nonnull %0) #5 |
| %arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %env_buffer, i64 0, i64 0 |
| %call = call signext i32 @_setjmp(%struct.__jmp_buf_tag* nonnull %arraydecay) #6 |
| %cmp1 = icmp ne i32 %argc, 2 |
| %cmp2 = icmp eq i32 %call, 0 |
| %or.cond = and i1 %cmp1, %cmp2 |
| br i1 %or.cond, label %if.then3, label %if.end5 |
| |
| if.then3: ; preds = %if.end |
| %1 = alloca [8 x i8], align 16 |
| %.sub = getelementptr inbounds [8 x i8], [8 x i8]* %1, i64 0, i64 0 |
| store i8 -1, i8* %.sub, align 16 |
| call void @test(i8* nonnull %.sub, %struct.__jmp_buf_tag* nonnull %arraydecay) #7 |
| unreachable |
| |
| if.end5: ; preds = %if.end |
| %call6 = call signext i32 (i8*, ...) @printf(i8* nonnull dereferenceable(1) getelementptr inbounds ([33 x i8], [33 x i8]* @.str, i64 0, i64 0)) |
| call void @llvm.lifetime.end.p0i8(i64 656, i8* nonnull %0) #5 |
| br label %return |
| |
| return: ; preds = %entry, %if.end5 |
| %retval.0 = phi i32 [ %call6, %if.end5 ], [ 0, %entry ] |
| ret i32 %retval.0 |
| } |
| |
| ; Function Attrs: argmemonly nofree nosync nounwind willreturn |
| declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) |
| |
| ; Function Attrs: nounwind returns_twice |
| declare signext i32 @_setjmp(%struct.__jmp_buf_tag*) local_unnamed_addr |
| |
| ; Function Attrs: noreturn |
| declare void @test(i8*, %struct.__jmp_buf_tag*) local_unnamed_addr |
| |
| ; Function Attrs: nofree nounwind |
| declare noundef signext i32 @printf(i8* nocapture noundef readonly, ...) local_unnamed_addr |
| |
| ; Function Attrs: argmemonly nofree nosync nounwind willreturn |
| declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) |
| |
| attributes #0 = { nounwind } |
| attributes #6 = { nounwind returns_twice } |