Files
Nikita Popov fcfc9167b6 Reapply [IR] Explicitly specify target feature for module asm (#204548) (#207677)
Reapply with a use-after-free fix. The MC subtarget used for inline
assembly has to stay alive until finalization, not only during the
emitInlineAsm() call.

-----

Support specifying additional properties on module-level inline
assembly. In particular, the target features and target CPU can now be
specified as follows:

    module asm(target_features: "+foo", target_cpu: "bar")
        "asm line 1"
        "asm line 2"

There may be multiple module inline assembly blocks with different
properties.

This is intended to fix the long standing issue where in LTO scenarios
we don't know what target features to use for parsing the module-level
inline assembly. Now they can be faithfully preserved, even when merging
inline assembly from different modules with different features.

If target_features and target_cpu are empty, we fall back to the old
behavior (which, in the backend, would be to use the default subtarget
of the TargetMachine).

Fixes https://github.com/llvm/llvm-project/issues/61991.
Fixes https://github.com/llvm/llvm-project/issues/67698.
2026-07-06 11:57:38 +02:00

88 lines
3.3 KiB
LLVM

; RUN: llvm-dis < %s.bc| FileCheck %s
; highLevelStructure.3.2.ll.bc was generated by passing this file to llvm-as-3.2.
; The test checks that LLVM does not misread binary float instructions of
; older bitcode files.
; Data Layout Test
; CHECK: target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-a0:0:64-f80:32:32-n8:16:32-S32"
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-a0:0:64-f80:32:32-n8:16:32-S32"
; Module-Level Inline Assembly Test
; CHECK: module asm
; CHECK-NEXT: "some assembly"
module asm "some assembly"
; Named Types Test
; CHECK: %mytype = type { ptr, i32 }
%mytype = type { %mytype*, i32 }
; Aliases Test
; CHECK: @glob1 = global i32 1
@glob1 = global i32 1
; CHECK: @aliased1 = alias i32, ptr @glob1
@aliased1 = alias i32, i32* @glob1
; CHECK-NEXT: @aliased2 = internal alias i32, ptr @glob1
@aliased2 = internal alias i32, i32* @glob1
; CHECK-NEXT: @aliased3 = alias i32, ptr @glob1
@aliased3 = external alias i32, i32* @glob1
; CHECK-NEXT: @aliased4 = weak alias i32, ptr @glob1
@aliased4 = weak alias i32, i32* @glob1
; CHECK-NEXT: @aliased5 = weak_odr alias i32, ptr @glob1
@aliased5 = weak_odr alias i32, i32* @glob1
;Parameter Attribute Test
; CHECK: declare void @ParamAttr1(i8 zeroext)
declare void @ParamAttr1(i8 zeroext)
; CHECK: declare void @ParamAttr2(ptr nest)
declare void @ParamAttr2(i8* nest)
; CHECK: declare void @ParamAttr3(ptr sret(i8))
declare void @ParamAttr3(i8* sret(i8))
; CHECK: declare void @ParamAttr4(i8 signext)
declare void @ParamAttr4(i8 signext)
; CHECK: declare void @ParamAttr5(ptr inreg)
declare void @ParamAttr5(i8* inreg)
; CHECK: declare void @ParamAttr6(ptr byval(i8))
declare void @ParamAttr6(i8* byval(i8))
; CHECK: declare void @ParamAttr7(ptr noalias)
declare void @ParamAttr7(i8* noalias)
; CHECK: declare void @ParamAttr8(ptr captures(none))
declare void @ParamAttr8(i8* nocapture)
; CHECK: declare void @ParamAttr9{{[(i8* nest noalias captures(none)) | (i8* noalias nocapture nest)]}}
declare void @ParamAttr9(i8* nest noalias captures(none))
; CHECK: declare void @ParamAttr10{{[(i8* sret(i8) noalias nocapture) | (i8* noalias captures(none) sret(i8))]}}
declare void @ParamAttr10(i8* sret(i8) noalias nocapture)
;CHECK: declare void @ParamAttr11{{[(i8* byval(i8) noalias captures(none)) | (i8* noalias nocapture byval(i8))]}}
declare void @ParamAttr11(i8* byval(i8) noalias nocapture)
;CHECK: declare void @ParamAttr12{{[(i8* inreg noalias captures(none)) | (i8* noalias nocapture inreg)]}}
declare void @ParamAttr12(i8* inreg noalias nocapture)
; NamedTypesTest
define void @NamedTypes() {
entry:
; CHECK: %res = alloca %mytype
%res = alloca %mytype
ret void
}
; Garbage Collector Name Test
; CHECK: define void @gcTest() gc "gc"
define void @gcTest() gc "gc" {
entry:
ret void
}
; Named metadata Test
; CHECK: !name = !{!0, !1, !2}
!name = !{!0, !1, !2}
; CHECK: !0 = !{!"zero"}
!0 = metadata !{metadata !"zero"}
; CHECK: !1 = !{!"one"}
!1 = metadata !{metadata !"one"}
; CHECK: !2 = !{!"two"}
!2 = metadata !{metadata !"two"}