374 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "E-p:64:64:64-p1:16:16:16-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"5 6; Simple case, argument translatable without changing the value7declare void @test1a(ptr)8 9define void @test1(ptr %A) {10; CHECK-LABEL: define void @test111; CHECK-SAME: (ptr [[A:%.*]]) {12; CHECK-NEXT: call void @test1a(ptr [[A]])13; CHECK-NEXT: ret void14;15 call void @test1a( ptr %A )16 ret void17}18 19 20; Should not do because of change in address space of the parameter21define void @test1_as1_illegal(ptr addrspace(1) %A) {22; CHECK-LABEL: define void @test1_as1_illegal23; CHECK-SAME: (ptr addrspace(1) [[A:%.*]]) {24; CHECK-NEXT: call void @test1a(ptr addrspace(1) [[A]])25; CHECK-NEXT: ret void26;27 call void @test1a(ptr addrspace(1) %A)28 ret void29}30 31; Test1, but the argument has a different sized address-space32declare void @test1a_as1(ptr addrspace(1))33 34; This one is OK to perform35define void @test1_as1(ptr addrspace(1) %A) {36; CHECK-LABEL: define void @test1_as137; CHECK-SAME: (ptr addrspace(1) [[A:%.*]]) {38; CHECK-NEXT: call void @test1a_as1(ptr addrspace(1) [[A]])39; CHECK-NEXT: ret void40;41 call void @test1a_as1(ptr addrspace(1) %A )42 ret void43}44 45; More complex case, translate argument because of resolution. This is safe46; because we have the body of the function47define void @test2a(i8 %A) {48; CHECK-LABEL: define void @test2a49; CHECK-SAME: (i8 [[A:%.*]]) {50; CHECK-NEXT: ret void51;52 ret void53}54 55define i32 @test2(i32 %A) {56; CHECK-LABEL: define i32 @test257; CHECK-SAME: (i32 [[A:%.*]]) {58; CHECK-NEXT: call void @test2a(i32 [[A]])59; CHECK-NEXT: ret i32 [[A]]60;61 call void @test2a( i32 %A )62 ret i32 %A63}64 65 66; Resolving this should insert a cast from sbyte to int, following the C67; promotion rules.68define void @test3a(i8, ...) {unreachable }69; CHECK-LABEL: define void @test3a70; CHECK-SAME: (i8 [[TMP0:%.*]], ...) {71; CHECK-NEXT: unreachable72;73define void @test3(i8 %A, i8 %B) {74 call void @test3a( i8 %A, i8 %B)75 ret void76}77 78; test conversion of return value...79define i8 @test4a() {80; CHECK-LABEL: define i8 @test4a() {81; CHECK-NEXT: ret i8 082;83 ret i8 084}85 86define i32 @test4() {87; CHECK-LABEL: define i32 @test4() {88; CHECK-NEXT: [[X:%.*]] = call i32 @test4a()89; CHECK-NEXT: ret i32 [[X]]90;91 %X = call i32 @test4a( ) ; <i32> [#uses=1]92 ret i32 %X93}94 95; test conversion of return value... no value conversion occurs so we can do96; this with just a prototype...97declare i32 @test5a()98 99define i32 @test5() {100; CHECK-LABEL: define i32 @test5() {101; CHECK-NEXT: [[X:%.*]] = call i32 @test5a()102; CHECK-NEXT: ret i32 [[X]]103;104 %X = call i32 @test5a( ) ; <i32> [#uses=1]105 ret i32 %X106}107 108; test addition of new arguments...109declare i32 @test6a(i32)110 111define i32 @test6() {112; CHECK-LABEL: define i32 @test6() {113; CHECK-NEXT: [[X:%.*]] = call i32 @test6a()114; CHECK-NEXT: ret i32 [[X]]115;116 %X = call i32 @test6a( )117 ret i32 %X118}119 120; test removal of arguments, only can happen with a function body121define void @test7a() {122; CHECK-LABEL: define void @test7a() {123; CHECK-NEXT: ret void124;125 ret void126}127 128define void @test7() {129; CHECK-LABEL: define void @test7() {130; CHECK-NEXT: call void @test7a()131; CHECK-NEXT: ret void132;133 call void @test7a( i32 5 )134 ret void135}136 137 138; rdar://7590304139declare void @test8a()140 141define ptr @test8() personality ptr @__gxx_personality_v0 {142; CHECK-LABEL: define ptr @test8() personality ptr @__gxx_personality_v0 {143; CHECK-NEXT: invoke void @test8a()144; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[TRY_HANDLER:%.*]]145; CHECK: invoke.cont:146; CHECK-NEXT: unreachable147; CHECK: try.handler:148; CHECK-NEXT: [[EXN:%.*]] = landingpad { ptr, i32 }149; CHECK-NEXT: cleanup150; CHECK-NEXT: ret ptr null151;152; Don't turn this into "unreachable": the callee and caller don't agree in153; calling conv, but the implementation of test8a may actually end up using the154; right calling conv.155 invoke void @test8a()156 to label %invoke.cont unwind label %try.handler157 158invoke.cont: ; preds = %entry159 unreachable160 161try.handler: ; preds = %entry162 %exn = landingpad {ptr, i32}163 cleanup164 ret ptr null165}166 167declare i32 @__gxx_personality_v0(...)168 169 170; Don't turn this into a direct call, because test9x is just a prototype and171; doing so will make it varargs.172; rdar://9038601173declare ptr @test9x(ptr, ptr, ...) noredzone174define ptr @test9(ptr %arg, ptr %tmp3) nounwind ssp noredzone {175; CHECK-LABEL: define ptr @test9176; CHECK-SAME: (ptr [[ARG:%.*]], ptr [[TMP3:%.*]]) #[[ATTR1:[0-9]+]] {177; CHECK-NEXT: entry:178; CHECK-NEXT: [[CALL:%.*]] = call ptr @test9x(ptr [[ARG]], ptr [[TMP3]]) #[[ATTR2:[0-9]+]]179; CHECK-NEXT: ret ptr [[CALL]]180;181entry:182 %call = call ptr @test9x(ptr %arg, ptr %tmp3) noredzone183 ret ptr %call184}185 186 187; Parameter that's a vector of pointers188declare void @test10a(<2 x ptr>)189 190define void @test10(<2 x ptr> %A) {191; CHECK-LABEL: define void @test10192; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {193; CHECK-NEXT: call void @test10a(<2 x ptr> [[A]])194; CHECK-NEXT: ret void195;196 call void @test10a(<2 x ptr> %A)197 ret void198}199 200; Don't transform because different address spaces201declare void @test10a_mixed_as(<2 x ptr addrspace(1)>)202 203define void @test10_mixed_as(<2 x ptr> %A) {204; CHECK-LABEL: define void @test10_mixed_as205; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {206; CHECK-NEXT: call void @test10a_mixed_as(<2 x ptr> [[A]])207; CHECK-NEXT: ret void208;209 call void @test10a_mixed_as(<2 x ptr> %A)210 ret void211}212 213; Return type that's a pointer214define ptr @test11a() {215; CHECK-LABEL: define ptr @test11a() {216; CHECK-NEXT: ret ptr null217;218 ret ptr zeroinitializer219}220 221define ptr @test11() {222; CHECK-LABEL: define ptr @test11() {223; CHECK-NEXT: [[X:%.*]] = call ptr @test11a()224; CHECK-NEXT: ret ptr [[X]]225;226 %X = call ptr @test11a()227 ret ptr %X228}229 230; Return type that's a pointer with a different address space231define ptr addrspace(1) @test11a_mixed_as() {232; CHECK-LABEL: define ptr addrspace(1) @test11a_mixed_as() {233; CHECK-NEXT: ret ptr addrspace(1) null234;235 ret ptr addrspace(1) zeroinitializer236}237 238define ptr @test11_mixed_as() {239; CHECK-LABEL: define ptr @test11_mixed_as() {240; CHECK-NEXT: [[X:%.*]] = call ptr @test11a_mixed_as()241; CHECK-NEXT: ret ptr [[X]]242;243 %X = call ptr @test11a_mixed_as()244 ret ptr %X245}246 247; Return type that's a vector of pointers248define <2 x ptr> @test12a() {249; CHECK-LABEL: define <2 x ptr> @test12a() {250; CHECK-NEXT: ret <2 x ptr> zeroinitializer251;252 ret <2 x ptr> zeroinitializer253}254 255define <2 x ptr> @test12() {256; CHECK-LABEL: define <2 x ptr> @test12() {257; CHECK-NEXT: [[X:%.*]] = call <2 x ptr> @test12a()258; CHECK-NEXT: ret <2 x ptr> [[X]]259;260 %X = call <2 x ptr> @test12a()261 ret <2 x ptr> %X262}263 264define <2 x ptr addrspace(1)> @test12a_mixed_as() {265; CHECK-LABEL: define <2 x ptr addrspace(1)> @test12a_mixed_as() {266; CHECK-NEXT: ret <2 x ptr addrspace(1)> zeroinitializer267;268 ret <2 x ptr addrspace(1)> zeroinitializer269}270 271define <2 x ptr> @test12_mixed_as() {272; CHECK-LABEL: define <2 x ptr> @test12_mixed_as() {273; CHECK-NEXT: [[X:%.*]] = call <2 x ptr> @test12a_mixed_as()274; CHECK-NEXT: ret <2 x ptr> [[X]]275;276 %X = call <2 x ptr> @test12a_mixed_as()277 ret <2 x ptr> %X278}279 280 281; Mix parameter that's a vector of integers and pointers of the same size282declare void @test13a(<2 x i64>)283 284define void @test13(<2 x ptr> %A) {285; CHECK-LABEL: define void @test13286; CHECK-SAME: (<2 x ptr> [[A:%.*]]) {287; CHECK-NEXT: call void @test13a(<2 x ptr> [[A]])288; CHECK-NEXT: ret void289;290 call void @test13a(<2 x ptr> %A)291 ret void292}293 294; Mix parameter that's a vector of integers and pointers of the same295; size, but the other way around296declare void @test14a(<2 x ptr>)297 298define void @test14(<2 x i64> %A) {299; CHECK-LABEL: define void @test14300; CHECK-SAME: (<2 x i64> [[A:%.*]]) {301; CHECK-NEXT: call void @test14a(<2 x i64> [[A]])302; CHECK-NEXT: ret void303;304 call void @test14a(<2 x i64> %A)305 ret void306}307 308 309; Return type that's a vector310define <2 x i16> @test15a() {311; CHECK-LABEL: define <2 x i16> @test15a() {312; CHECK-NEXT: ret <2 x i16> zeroinitializer313;314 ret <2 x i16> zeroinitializer315}316 317define i32 @test15() {318; CHECK-LABEL: define i32 @test15() {319; CHECK-NEXT: [[X:%.*]] = call <2 x i16> @test15a()320; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i16> [[X]] to i32321; CHECK-NEXT: ret i32 [[TMP1]]322;323 %X = call i32 @test15a( )324 ret i32 %X325}326 327define i32 @test16a() {328; CHECK-LABEL: define i32 @test16a() {329; CHECK-NEXT: ret i32 0330;331 ret i32 0332}333 334define <2 x i16> @test16() {335; CHECK-LABEL: define <2 x i16> @test16() {336; CHECK-NEXT: [[X:%.*]] = call i32 @test16a()337; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[X]] to <2 x i16>338; CHECK-NEXT: ret <2 x i16> [[TMP1]]339;340 %X = call <2 x i16> @test16a( )341 ret <2 x i16> %X342}343 344declare i32 @pr28655(i32 returned %V)345 346define i32 @test17() {347; CHECK-LABEL: define i32 @test17() {348; CHECK-NEXT: entry:349; CHECK-NEXT: [[C:%.*]] = call i32 @pr28655(i32 0)350; CHECK-NEXT: ret i32 0351;352entry:353 %C = call i32 @pr28655(i32 0)354 ret i32 %C355}356 357define void @non_vararg(ptr, i32) {358; CHECK-LABEL: define void @non_vararg359; CHECK-SAME: (ptr [[TMP0:%.*]], i32 [[TMP1:%.*]]) {360; CHECK-NEXT: ret void361;362 ret void363}364 365define void @test_cast_to_vararg(ptr %this) {366; CHECK-LABEL: define void @test_cast_to_vararg367; CHECK-SAME: (ptr [[THIS:%.*]]) {368; CHECK-NEXT: call void @non_vararg(ptr [[THIS]], i32 42)369; CHECK-NEXT: ret void370;371 call void (ptr, ...) @non_vararg(ptr %this, i32 42)372 ret void373}374