1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4target datalayout = "e-p:32:32" 5target triple = "i686-pc-linux-gnu" 6 7define i32 @main() { 8; CHECK-LABEL: define i32 @main() { 9; CHECK-NEXT: [[ENTRY:.*:]] 10; CHECK-NEXT: [[TMP:%.*]] = call ptr @ctime(ptr null) 11; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[TMP]] to i32 12; CHECK-NEXT: ret i32 [[TMP0]] 13; 14entry: 15 %tmp = call i32 @ctime( ptr null ) ; <i32> [#uses=1] 16 ret i32 %tmp 17} 18 19define ptr @ctime(ptr %p) { 20; CHECK-LABEL: define ptr @ctime( 21; CHECK-SAME: ptr [[P:%.*]]) { 22; CHECK-NEXT: ret ptr [[P]] 23; 24 ret ptr %p 25} 26 27define internal { i8 } @foo(ptr) { 28; CHECK-LABEL: define internal { i8 } @foo( 29; CHECK-SAME: ptr [[TMP0:%.*]]) { 30; CHECK-NEXT: [[ENTRY:.*:]] 31; CHECK-NEXT: ret { i8 } zeroinitializer 32; 33entry: 34 ret { i8 } { i8 0 } 35} 36 37define void @test_struct_ret() { 38; CHECK-LABEL: define void @test_struct_ret() { 39; CHECK-NEXT: [[ENTRY:.*:]] 40; CHECK-NEXT: [[TMP0:%.*]] = call { i8 } @foo(ptr null) 41; CHECK-NEXT: ret void 42; 43entry: 44 %0 = call { i8 } @foo(ptr null) 45 ret void 46} 47 48define i32 @fn1(i32 %x) { 49; CHECK-LABEL: define i32 @fn1( 50; CHECK-SAME: i32 [[X:%.*]]) { 51; CHECK-NEXT: ret i32 [[X]] 52; 53 ret i32 %x 54} 55 56define i32 @test1(ptr %a) { 57; CHECK-LABEL: define i32 @test1( 58; CHECK-SAME: ptr [[A:%.*]]) { 59; CHECK-NEXT: [[ENTRY:.*:]] 60; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i32 61; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @fn1(i32 [[TMP0]]) 62; CHECK-NEXT: ret i32 [[CALL]] 63; 64entry: 65 %call = tail call i32 @fn1(ptr %a) 66 ret i32 %call 67} 68 69declare i32 @fn2(i16) 70 71define i32 @test2(ptr %a) { 72; CHECK-LABEL: define i32 @test2( 73; CHECK-SAME: ptr [[A:%.*]]) { 74; CHECK-NEXT: [[ENTRY:.*:]] 75; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @fn2(ptr [[A]]) 76; CHECK-NEXT: ret i32 [[CALL]] 77; 78entry: 79 %call = tail call i32 @fn2(ptr %a) 80 ret i32 %call 81} 82 83declare i32 @fn3(i64) 84 85define i32 @test3(ptr %a) { 86; CHECK-LABEL: define i32 @test3( 87; CHECK-SAME: ptr [[A:%.*]]) { 88; CHECK-NEXT: [[ENTRY:.*:]] 89; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @fn3(ptr [[A]]) 90; CHECK-NEXT: ret i32 [[CALL]] 91; 92entry: 93 %call = tail call i32 @fn3(ptr %a) 94 ret i32 %call 95} 96 97declare i32 @fn4(i32) "thunk" 98 99define i32 @test4(ptr %a) { 100; CHECK-LABEL: define i32 @test4( 101; CHECK-SAME: ptr [[A:%.*]]) { 102; CHECK-NEXT: [[ENTRY:.*:]] 103; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @fn4(ptr [[A]]) 104; CHECK-NEXT: ret i32 [[CALL]] 105; 106entry: 107 %call = tail call i32 @fn4(ptr %a) 108 ret i32 %call 109} 110 111declare i1 @fn5(ptr byval({ i32, i32 }) align 4 %r) 112 113define i1 @test5() { 114; CHECK-LABEL: define i1 @test5() { 115; CHECK-NEXT: [[TMP1:%.*]] = alloca { i32, i32 }, align 4 116; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 4 117; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP1]], i32 4 118; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP3]], align 4 119; CHECK-NEXT: [[TMP5:%.*]] = call i1 @fn5(i32 [[TMP2]], i32 [[TMP4]]) 120; CHECK-NEXT: ret i1 [[TMP5]] 121; 122 %1 = alloca { i32, i32 }, align 4 123 %2 = getelementptr inbounds { i32, i32 }, ptr %1, i32 0, i32 0 124 %3 = load i32, ptr %2, align 4 125 %4 = getelementptr inbounds { i32, i32 }, ptr %1, i32 0, i32 1 126 %5 = load i32, ptr %4, align 4 127 %6 = call i1 @fn5(i32 %3, i32 %5) 128 ret i1 %6 129} 130 131define void @bundles_callee(i32) { 132; CHECK-LABEL: define void @bundles_callee( 133; CHECK-SAME: i32 [[TMP0:%.*]]) { 134; CHECK-NEXT: ret void 135; 136 ret void 137} 138 139define void @bundles() { 140; CHECK-LABEL: define void @bundles() { 141; CHECK-NEXT: [[ENTRY:.*:]] 142; CHECK-NEXT: call void @bundles_callee(i32 0) [ "deopt"() ] 143; CHECK-NEXT: ret void 144; 145entry: 146 call void @bundles_callee() [ "deopt"() ] 147 ret void 148} 149