Cannot interchange "literal" and "identified" structs

With primitive types, I can interchange literal usage and type aliases in IR:

%mytype = type i32

define void @foo(%mytype* %ptr) {
%t1 = load %mytype* %ptr
store i32 %t1, i32* %ptr
ret void
}

But for structs, I cannot:

%mytype = type { i32, i32 }

define void @foo(%mytype* %ptr) {
%t1 = load %mytype* %ptr
store { i32, i32 } %t1, { i32, i32 }* %ptr
ret void
}

bin/llvm-as: alias2.ll:6:22: error: ‘%t1’ defined with type ‘%mytype = type { i32, i32 }’
store { i32, i32 } %t1, { i32, i32 }* %ptr

I don’t see anything in the language reference manual that disallows such usage, as the literal struct type and %mytype are equivalent. Am I missing something here, or is this just a bug in the assembly parser?

Justin,

http://llvm.org/docs/LangRef.html#structure-type
"Identified types can be recursive, can be opaqued, and are never uniqued."
Do you think it would be less descriptive?

"Identified type, aka named llvm::StructType, is never uniqued against
other identified types nor literal types, aka unnamed StructType(s)."
?

See also; LLVM 3.0 Type System Rewrite - The LLVM Project Blog

...Takumi

Alright, I misunderstood that statement then. This does seem to be inconsistent with llvm-link, though. If I have two identified structs in the same module, I cannot interchange them. But if they are in different modules, llvm-link will merge them:

$ cat struct1.ll

%mystruct = type { i32, i32 }

define i32 @foo(i32 %a) {
%val = tail call %mystruct @llvm.my.intrinsic(i32 %a)
%ret = extractvalue %mystruct %val, 0
ret i32 %ret
}

declare %mystruct @llvm.my.intrinsic(i32)

$ cat struct2.ll

%mytype = type { i32, i32 }

define i32 @bar(i32 %a) {
%val = tail call %mytype @llvm.my.intrinsic(i32 %a)
%ret = extractvalue %mytype %val, 1
ret i32 %ret
}

declare %mytype @llvm.my.intrinsic(i32)

$ bin/llvm-link struct1.ll struct2.ll -S
; ModuleID = ‘struct1.ll’

%mystruct = type { i32, i32 }

define i32 @foo(i32 %a) {
%val = tail call %mystruct @llvm.my.intrinsic(i32 %a)
%ret = extractvalue %mystruct %val, 0
ret i32 %ret
}

declare %mystruct @llvm.my.intrinsic(i32)

define i32 @bar(i32 %a) {
%val = tail call %mystruct @llvm.my.intrinsic(i32 %a)
%ret = extractvalue %mystruct %val, 1
ret i32 %ret
}