| ; RUN: opt -S -passes=mergefunc < %s | FileCheck %s |
| |
| target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32" |
| |
| %A = type { double } |
| ; the intermediary struct causes A_arr and B_arr to be different types |
| %A_struct = type { %A } |
| %A_arr = type { [1 x %A_struct] } |
| |
| %B = type { double } |
| %B_struct = type { %B } |
| %B_arr = type { [1 x %B_struct] } |
| |
| ; conversion between C_arr and D_arr is possible, but requires ptrcast |
| %C = type { i64 } |
| %C_struct = type { %C } |
| %C_arr = type { [1 x %C_struct] } |
| |
| %D = type { ptr } |
| %D_struct = type { %D } |
| %D_arr = type { [1 x %D_struct] } |
| |
| declare void @noop() |
| |
| define %A_arr @a() { |
| ; CHECK-LABEL: define %A_arr @a() { |
| ; CHECK-NEXT: call void @noop() |
| ; CHECK-NEXT: ret %A_arr zeroinitializer |
| ; |
| call void @noop() |
| ret %A_arr zeroinitializer |
| } |
| |
| define %C_arr @c() { |
| ; CHECK-LABEL: define %C_arr @c() { |
| ; CHECK-NEXT: call void @noop() |
| ; CHECK-NEXT: ret %C_arr zeroinitializer |
| ; |
| call void @noop() |
| ret %C_arr zeroinitializer |
| } |
| |
| define %B_arr @b() { |
| ; CHECK-LABEL: define %B_arr @b() { |
| ; CHECK-NEXT: [[TMP1:%.*]] = tail call %A_arr @a |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue %A_arr [[TMP1]], 0 |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [1 x %A_struct] [[TMP2]], 0 |
| ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue %A_struct [[TMP3]], 0 |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractvalue %A [[TMP4]], 0 |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue %B poison, double [[TMP5]], 0 |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue %B_struct poison, %B [[TMP6]], 0 |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue [1 x %B_struct] poison, %B_struct [[TMP7]], 0 |
| ; CHECK-NEXT: [[TMP9:%.*]] = insertvalue %B_arr poison, [1 x %B_struct] [[TMP8]], 0 |
| ; CHECK-NEXT: ret %B_arr [[TMP9]] |
| ; |
| call void @noop() |
| ret %B_arr zeroinitializer |
| } |
| |
| define %D_arr @d() { |
| ; CHECK-LABEL: define %D_arr @d() { |
| ; CHECK-NEXT: [[TMP1:%.*]] = tail call %C_arr @c |
| ; CHECK-NEXT: [[TMP2:%.*]] = extractvalue %C_arr [[TMP1]], 0 |
| ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue [1 x %C_struct] [[TMP2]], 0 |
| ; CHECK-NEXT: [[TMP4:%.*]] = extractvalue %C_struct [[TMP3]], 0 |
| ; CHECK-NEXT: [[TMP5:%.*]] = extractvalue %C [[TMP4]], 0 |
| ; CHECK-NEXT: [[TMP10:%.*]] = inttoptr i64 [[TMP5]] to ptr |
| ; CHECK-NEXT: [[TMP6:%.*]] = insertvalue %D poison, ptr [[TMP10]], 0 |
| ; CHECK-NEXT: [[TMP7:%.*]] = insertvalue %D_struct poison, %D [[TMP6]], 0 |
| ; CHECK-NEXT: [[TMP8:%.*]] = insertvalue [1 x %D_struct] poison, %D_struct [[TMP7]], 0 |
| ; CHECK-NEXT: [[TMP9:%.*]] = insertvalue %D_arr poison, [1 x %D_struct] [[TMP8]], 0 |
| ; CHECK-NEXT: ret %D_arr [[TMP9]] |
| ; |
| call void @noop() |
| ret %D_arr zeroinitializer |
| } |