This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb0343a38a591: Support the min of module flags when linking, 
use for AArch64 BTI/PAC-RET (authored by danielkiss).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D123493/new/

https://reviews.llvm.org/D123493

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/aarch64-sign-return-address.c
  clang/test/CodeGen/arm-branch-protection-attr-2.c
  clang/test/Frontend/arm-ignore-branch-protection-option.c
  llvm/include/llvm/IR/Module.h
  llvm/lib/IR/AutoUpgrade.cpp
  llvm/lib/IR/Verifier.cpp
  llvm/lib/Linker/IRMover.cpp
  llvm/test/Bitcode/upgrade-branch-protection.ll
  llvm/test/CodeGen/AArch64/debug-info-sve-dbg-declare.mir
  llvm/test/CodeGen/AArch64/live-debugvalues-sve.mir
  llvm/test/CodeGen/AArch64/memsize-remarks.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
  llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
  llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
  llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
  llvm/test/CodeGen/AArch64/setjmp-bti-no-enforcement.ll
  llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
  llvm/test/CodeGen/AArch64/setjmp-bti.ll
  llvm/test/CodeGen/ARM/pacbti-module-attrs.ll
  llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
  llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
  llvm/test/CodeGen/Thumb2/LowOverheadLoops/skip-vpt-debug.mir
  llvm/test/CodeGen/Thumb2/bti-const-island-multiple-jump-tables.mir
  llvm/test/CodeGen/Thumb2/bti-const-island.mir
  llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
  llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
  llvm/test/CodeGen/Thumb2/bti-jump-table.mir
  llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
  llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
  llvm/test/CodeGen/Thumb2/bti-outliner-cost-1.ll
  llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
  llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
  llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-outliner-2.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
  llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
  llvm/test/DebugInfo/AArch64/debugline-endsequence.ll
  llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-coverage.ll
  llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
  llvm/test/LTO/AArch64/Inputs/foo.ll
  llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
  llvm/test/LTO/AArch64/lit.local.cfg
  llvm/test/Verifier/module-flags-1.ll

Index: llvm/test/Verifier/module-flags-1.ll
===================================================================
--- llvm/test/Verifier/module-flags-1.ll
+++ llvm/test/Verifier/module-flags-1.ll
@@ -45,6 +45,10 @@
 ; CHECK: invalid value for 'max' module flag (expected constant integer)
 !19 = !{i32 7, !"max", !"max"}
 
+; Check that any 'min' module flags are valid.
+; CHECK: invalid value for 'min' module flag (expected constant integer)
+!20 = !{i32 8, !"min", !"min"}
+
 ; Check that any 'require' module flags are valid.
 ; CHECK: invalid requirement on flag, flag is not present in module
 !11 = !{i32 3, !"bar", !{!"no-such-flag", i32 52}}
@@ -58,4 +62,4 @@
 
 !llvm.module.flags = !{
   !0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15,
-  !16, !17, !18, !19 }
+  !16, !17, !18, !19, !20 }
Index: llvm/test/LTO/AArch64/lit.local.cfg
===================================================================
--- /dev/null
+++ llvm/test/LTO/AArch64/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'AArch64' in config.root.targets:
+  config.unsupported = True
Index: llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
===================================================================
--- /dev/null
+++ llvm/test/LTO/AArch64/link-branch-target-enforcement.ll
@@ -0,0 +1,38 @@
+; Testcase to check that module with different branch-target-enforcement can
+; be mixed.
+;
+; RUN: llvm-as %s -o %t1.bc
+; RUN: llvm-as %p/Inputs/foo.ll -o %t2.bc
+; RUN: llvm-lto -exported-symbol main \
+; RUN:          -exported-symbol foo \
+; RUN:          -filetype=obj \
+; RUN:           %t1.bc %t2.bc \
+; RUN:           -o %t1.exe 2>&1 | FileCheck --allow-empty %s
+; RUN: llvm-objdump -d %t1.exe | FileCheck --check-prefix=CHECK-DUMP %s
+; RUN: llvm-readelf -n %t1.exe | FileCheck --check-prefix=CHECK-PROP %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+declare i32 @foo();
+
+define i32 @main() {
+entry:
+  %add = call i32 @foo()
+  ret i32 %add
+}
+
+!llvm.module.flags = !{!0, !1, !2, !3 }
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
+
+; CHECK-NOT: linking module flags 'branch-target-enforcement': IDs have conflicting values in
+; CHECK-DUMP: <main>:
+; CHECK-DUMP:      bl      0x8 <main+0x8>
+; CHECK-DUMP: <foo>:
+
+; `main` doesn't support BTI while `foo` does, so in the binary
+; we should see only PAC which is supported by both.
+; CHECK-PROP:   Properties: aarch64 feature: PAC
\ No newline at end of file
Index: llvm/test/LTO/AArch64/Inputs/foo.ll
===================================================================
--- /dev/null
+++ llvm/test/LTO/AArch64/Inputs/foo.ll
@@ -0,0 +1,16 @@
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+define dso_local i32 @foo() #0 {
+entry:
+  ret i32 42
+}
+
+attributes #0 = { noinline nounwind optnone uwtable }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 1}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
Index: llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
===================================================================
--- llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
+++ llvm/test/Instrumentation/InstrProfiling/debug-info-correlate.ll
@@ -34,10 +34,10 @@
 !2 = !{i32 7, !"Dwarf Version", i32 4}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !4 = !{i32 1, !"wchar_size", i32 4}
-!5 = !{i32 1, !"branch-target-enforcement", i32 0}
-!6 = !{i32 1, !"sign-return-address", i32 0}
-!7 = !{i32 1, !"sign-return-address-all", i32 0}
-!8 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!5 = !{i32 8, !"branch-target-enforcement", i32 0}
+!6 = !{i32 8, !"sign-return-address", i32 0}
+!7 = !{i32 8, !"sign-return-address-all", i32 0}
+!8 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 !9 = !{i32 7, !"uwtable", i32 1}
 !10 = !{i32 7, !"frame-pointer", i32 1}
 !11 = !{!"clang version 14.0.0"}
Index: llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-coverage.ll
===================================================================
--- llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-coverage.ll
+++ llvm/test/Instrumentation/InstrProfiling/debug-info-correlate-coverage.ll
@@ -20,10 +20,10 @@
 !2 = !{i32 7, !"Dwarf Version", i32 4}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !4 = !{i32 1, !"wchar_size", i32 4}
-!5 = !{i32 1, !"branch-target-enforcement", i32 0}
-!6 = !{i32 1, !"sign-return-address", i32 0}
-!7 = !{i32 1, !"sign-return-address-all", i32 0}
-!8 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!5 = !{i32 8, !"branch-target-enforcement", i32 0}
+!6 = !{i32 8, !"sign-return-address", i32 0}
+!7 = !{i32 8, !"sign-return-address-all", i32 0}
+!8 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 !9 = !{i32 7, !"uwtable", i32 1}
 !10 = !{i32 7, !"frame-pointer", i32 1}
 !11 = !{!"clang version 14.0.0"}
Index: llvm/test/DebugInfo/AArch64/debugline-endsequence.ll
===================================================================
--- llvm/test/DebugInfo/AArch64/debugline-endsequence.ll
+++ llvm/test/DebugInfo/AArch64/debugline-endsequence.ll
@@ -46,10 +46,10 @@
 !7 = !{i32 7, !"Dwarf Version", i32 4}
 !8 = !{i32 2, !"Debug Info Version", i32 3}
 !9 = !{i32 1, !"wchar_size", i32 4}
-!10 = !{i32 1, !"branch-target-enforcement", i32 0}
-!11 = !{i32 1, !"sign-return-address", i32 0}
-!12 = !{i32 1, !"sign-return-address-all", i32 0}
-!13 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!10 = !{i32 8, !"branch-target-enforcement", i32 0}
+!11 = !{i32 8, !"sign-return-address", i32 0}
+!12 = !{i32 8, !"sign-return-address-all", i32 0}
+!13 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 !14 = !{i32 7, !"PIC Level", i32 2}
 !15 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 1, type: !16, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
 !16 = !DISubroutineType(types: !17)
Index: llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-vla.ll
@@ -120,6 +120,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-varargs-2.ll
@@ -90,9 +90,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ; UNWIND-LABEL: FunctionAddress
 ; UNWIND:       0x01      ; vsp = vsp + 8
Index: llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-varargs-1.ll
@@ -72,6 +72,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-unsupported-arch.ll
@@ -26,6 +26,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-overalign.ll
@@ -60,9 +60,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ; UNWIND-LABEL:        FunctionAddress: 0x0
 ; UNWIND:          0x97      ; vsp = r7
Index: llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-5.ll
@@ -93,6 +93,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-4.ll
@@ -172,9 +172,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 
 ; UNWIND-LABEL: FunctionAddress: 0x0
Index: llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-3.ll
@@ -138,9 +138,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 
 ; UNWIND-LABEL: FunctionAddress: 0x4
Index: llvm/test/CodeGen/Thumb2/pacbti-m-outliner-2.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-2.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-2.ll
@@ -84,6 +84,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-outliner-1.ll
@@ -120,9 +120,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ; UNWIND-LABEL: FunctionAddress: 0x0
 ; UNWIND:       0xB4      ; pop ra_auth_code
Index: llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-indirect-tail-call.ll
@@ -32,6 +32,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
+++ llvm/test/CodeGen/Thumb2/pacbti-m-basic.ll
@@ -97,9 +97,9 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ; UNWIND-LABEL: FunctionAddress: 0x0
 ; UNWIND:       0x00      ; vsp = vsp + 4
Index: llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
+++ llvm/test/CodeGen/Thumb2/bti-pac-replace-2.ll
@@ -14,9 +14,9 @@
 declare dso_local i32 @_Z1gi(i32)
 
 !llvm.module.flags = !{!0, !1, !2}
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ; Check the function starts with `pacbti` and correct unwind info is emitted
 ; CHECK-LABEL: _Z1fi:
Index: llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
+++ llvm/test/CodeGen/Thumb2/bti-pac-replace-1.mir
@@ -15,9 +15,9 @@
 
   !llvm.module.flags = !{!0, !1, !2}
 
-  !0 = !{i32 1, !"branch-target-enforcement", i32 1}
-  !1 = !{i32 1, !"sign-return-address", i32 1}
-  !2 = !{i32 1, !"sign-return-address-all", i32 0}
+  !0 = !{i32 8, !"branch-target-enforcement", i32 1}
+  !1 = !{i32 8, !"sign-return-address", i32 1}
+  !2 = !{i32 8, !"sign-return-address-all", i32 0}
 
 ...
 ---
Index: llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
+++ llvm/test/CodeGen/Thumb2/bti-outliner-cost-2.ll
@@ -48,4 +48,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/Thumb2/bti-outliner-cost-1.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-outliner-cost-1.ll
+++ llvm/test/CodeGen/Thumb2/bti-outliner-cost-1.ll
@@ -64,4 +64,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
Index: llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
+++ llvm/test/CodeGen/Thumb2/bti-outliner-2.ll
@@ -79,4 +79,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
+++ llvm/test/CodeGen/Thumb2/bti-outliner-1.ll
@@ -133,4 +133,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
Index: llvm/test/CodeGen/Thumb2/bti-jump-table.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-jump-table.mir
+++ llvm/test/CodeGen/Thumb2/bti-jump-table.mir
@@ -28,7 +28,7 @@
   }
 
   !llvm.module.flags = !{!0}
-  !0 = !{i32 1, !"branch-target-enforcement", i32 1}
+  !0 = !{i32 8, !"branch-target-enforcement", i32 1}
 
 ...
 ---
Index: llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
+++ llvm/test/CodeGen/Thumb2/bti-indirect-branches.ll
@@ -132,4 +132,4 @@
 }
 
 !llvm.module.flags = !{!1}
-!1 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
+++ llvm/test/CodeGen/Thumb2/bti-entry-blocks.ll
@@ -19,4 +19,4 @@
 }
 
 !llvm.module.flags = !{!1}
-!1 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/Thumb2/bti-const-island.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-const-island.mir
+++ llvm/test/CodeGen/Thumb2/bti-const-island.mir
@@ -43,7 +43,7 @@
   }
 
   !llvm.module.flags = !{!0}
-  !0 = !{i32 1, !"branch-target-enforcement", i32 1}
+  !0 = !{i32 8, !"branch-target-enforcement", i32 1}
 
 ...
 ---
Index: llvm/test/CodeGen/Thumb2/bti-const-island-multiple-jump-tables.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/bti-const-island-multiple-jump-tables.mir
+++ llvm/test/CodeGen/Thumb2/bti-const-island-multiple-jump-tables.mir
@@ -126,7 +126,7 @@
 
   !llvm.module.flags = !{!0}
 
-  !0 = !{i32 1, !"branch-target-enforcement", i32 1}
+  !0 = !{i32 8, !"branch-target-enforcement", i32 1}
 
 ...
 ---
Index: llvm/test/CodeGen/Thumb2/LowOverheadLoops/skip-vpt-debug.mir
===================================================================
--- llvm/test/CodeGen/Thumb2/LowOverheadLoops/skip-vpt-debug.mir
+++ llvm/test/CodeGen/Thumb2/LowOverheadLoops/skip-vpt-debug.mir
@@ -93,9 +93,9 @@
   !6 = !{i32 1, !"static_rwdata", i32 1}
   !7 = !{i32 1, !"enumsize_buildattr", i32 2}
   !8 = !{i32 1, !"armlib_unavailable", i32 0}
-  !9 = !{i32 1, !"branch-target-enforcement", i32 0}
-  !10 = !{i32 1, !"sign-return-address", i32 0}
-  !11 = !{i32 1, !"sign-return-address-all", i32 0}
+  !9 = !{i32 8, !"branch-target-enforcement", i32 0}
+  !10 = !{i32 8, !"sign-return-address", i32 0}
+  !11 = !{i32 8, !"sign-return-address-all", i32 0}
   !12 = !{!"Component: ARM Compiler 6.17.0.0 (permissive) Tool: armclang [00000000]"}
   !13 = distinct !DISubprogram(name: "arm_max_no_idx_f32", scope: !1, file: !1, line: 5, type: !14, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !23)
   !14 = !DISubroutineType(types: !15)
Index: llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
===================================================================
--- llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
+++ llvm/test/CodeGen/ARM/setjmp-bti-outliner.ll
@@ -89,4 +89,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
===================================================================
--- llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
+++ llvm/test/CodeGen/ARM/setjmp-bti-basic.ll
@@ -47,4 +47,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/ARM/pacbti-module-attrs.ll
===================================================================
--- llvm/test/CodeGen/ARM/pacbti-module-attrs.ll
+++ llvm/test/CodeGen/ARM/pacbti-module-attrs.ll
@@ -16,6 +16,6 @@
 
 !llvm.module.flags = !{!0, !1, !2}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
Index: llvm/test/CodeGen/AArch64/setjmp-bti.ll
===================================================================
--- llvm/test/CodeGen/AArch64/setjmp-bti.ll
+++ llvm/test/CodeGen/AArch64/setjmp-bti.ll
@@ -52,4 +52,4 @@
 attributes #0 = { returns_twice }
 
 !llvm.module.flags = !{!0}
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
===================================================================
--- llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
+++ llvm/test/CodeGen/AArch64/setjmp-bti-outliner.ll
@@ -80,4 +80,4 @@
 
 !llvm.module.flags = !{!0}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/AArch64/setjmp-bti-no-enforcement.ll
===================================================================
--- llvm/test/CodeGen/AArch64/setjmp-bti-no-enforcement.ll
+++ llvm/test/CodeGen/AArch64/setjmp-bti-no-enforcement.ll
@@ -48,4 +48,4 @@
 attributes #0 = { returns_twice }
 
 ; !llvm.module.flags = !{!0}
-; !0 = !{i32 1, !"branch-target-enforcement", i32 1}
+; !0 = !{i32 8, !"branch-target-enforcement", i32 1}
Index: llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
===================================================================
--- llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
+++ llvm/test/CodeGen/AArch64/pacbti-module-attrs.ll
@@ -71,7 +71,7 @@
 !llvm.module.flags = !{!0, !1, !2, !3, !4}
 
 !0 = !{i32 1, !"wchar_size", i32 4}
-!1 = !{i32 1, !"branch-target-enforcement", i32 1}
-!2 = !{i32 1, !"sign-return-address", i32 1}
-!3 = !{i32 1, !"sign-return-address-all", i32 0}
-!4 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!1 = !{i32 8, !"branch-target-enforcement", i32 1}
+!2 = !{i32 8, !"sign-return-address", i32 1}
+!3 = !{i32 8, !"sign-return-address-all", i32 0}
+!4 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
Index: llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
===================================================================
--- llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
+++ llvm/test/CodeGen/AArch64/pacbti-llvm-generated-funcs-2.ll
@@ -65,7 +65,7 @@
 
 !0 = !{i32 2, !"Debug Info Version", i32 3}
 !1 = !{i32 1, !"wchar_size", i32 4}
-!2 = !{i32 1, !"branch-target-enforcement", i32 0}
-!3 = !{i32 1, !"sign-return-address", i32 1}
-!4 = !{i32 1, !"sign-return-address-all", i32 1}
-!5 = !{i32 1, !"sign-return-address-with-bkey", i32 1}
+!2 = !{i32 8, !"branch-target-enforcement", i32 0}
+!3 = !{i32 8, !"sign-return-address", i32 1}
+!4 = !{i32 8, !"sign-return-address-all", i32 1}
+!5 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
+++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-4.ll
@@ -17,10 +17,10 @@
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 0}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
-!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 0}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; Note is not emited if module has no properties
 ; ASM-NOT: .note.gnu.property
\ No newline at end of file
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
+++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-3.ll
@@ -10,10 +10,10 @@
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
-!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; Both attribute present
 ; ASM:	    .word	3221225472
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
+++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-2.ll
@@ -10,10 +10,10 @@
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 0}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
-!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 0}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; PAC attribute present
 ; ASM:	    .word	3221225472
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
+++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-1.ll
@@ -10,10 +10,10 @@
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 0}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
-!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 0}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; BTI attribute present
 ; ASM:	    .word	3221225472
Index: llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
===================================================================
--- llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
+++ llvm/test/CodeGen/AArch64/note-gnu-property-pac-bti-0.ll
@@ -8,10 +8,10 @@
 
 !llvm.module.flags = !{!0, !1, !2, !3}
 
-!0 = !{i32 1, !"branch-target-enforcement", i32 1}
-!1 = !{i32 1, !"sign-return-address", i32 1}
-!2 = !{i32 1, !"sign-return-address-all", i32 0}
-!3 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!0 = !{i32 8, !"branch-target-enforcement", i32 1}
+!1 = !{i32 8, !"sign-return-address", i32 1}
+!2 = !{i32 8, !"sign-return-address-all", i32 0}
+!3 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 
 ; Both attributes present in a file with no functions.
 ; ASM:	    .word	3221225472
Index: llvm/test/CodeGen/AArch64/memsize-remarks.ll
===================================================================
--- llvm/test/CodeGen/AArch64/memsize-remarks.ll
+++ llvm/test/CodeGen/AArch64/memsize-remarks.ll
@@ -328,10 +328,10 @@
 !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 12, i32 0]}
 !1 = !{i32 2, !"Debug Info Version", i32 3}
 !2 = !{i32 1, !"wchar_size", i32 4}
-!3 = !{i32 1, !"branch-target-enforcement", i32 0}
-!4 = !{i32 1, !"sign-return-address", i32 0}
-!5 = !{i32 1, !"sign-return-address-all", i32 0}
-!6 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!3 = !{i32 8, !"branch-target-enforcement", i32 0}
+!4 = !{i32 8, !"sign-return-address", i32 0}
+!5 = !{i32 8, !"sign-return-address-all", i32 0}
+!6 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
 !7 = !{i32 7, !"PIC Level", i32 2}
 !8 = !{i32 7, !"uwtable", i32 1}
 !9 = !{i32 7, !"frame-pointer", i32 1}
Index: llvm/test/CodeGen/AArch64/live-debugvalues-sve.mir
===================================================================
--- llvm/test/CodeGen/AArch64/live-debugvalues-sve.mir
+++ llvm/test/CodeGen/AArch64/live-debugvalues-sve.mir
@@ -69,10 +69,10 @@
   !3 = !{i32 7, !"Dwarf Version", i32 4}
   !4 = !{i32 2, !"Debug Info Version", i32 3}
   !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{i32 1, !"branch-target-enforcement", i32 0}
-  !7 = !{i32 1, !"sign-return-address", i32 0}
-  !8 = !{i32 1, !"sign-return-address-all", i32 0}
-  !9 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+  !6 = !{i32 8, !"branch-target-enforcement", i32 0}
+  !7 = !{i32 8, !"sign-return-address", i32 0}
+  !8 = !{i32 8, !"sign-return-address-all", i32 0}
+  !9 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
   !10 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git b19275ba870a06c5ef0428af6264ffd28c7cde9e)"}
   !11 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 6, type: !12, scopeLine: 6, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !26)
   !12 = !DISubroutineType(types: !13)
Index: llvm/test/CodeGen/AArch64/debug-info-sve-dbg-declare.mir
===================================================================
--- llvm/test/CodeGen/AArch64/debug-info-sve-dbg-declare.mir
+++ llvm/test/CodeGen/AArch64/debug-info-sve-dbg-declare.mir
@@ -89,10 +89,10 @@
   !3 = !{i32 7, !"Dwarf Version", i32 4}
   !4 = !{i32 2, !"Debug Info Version", i32 3}
   !5 = !{i32 1, !"wchar_size", i32 4}
-  !6 = !{i32 1, !"branch-target-enforcement", i32 0}
-  !7 = !{i32 1, !"sign-return-address", i32 0}
-  !8 = !{i32 1, !"sign-return-address-all", i32 0}
-  !9 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+  !6 = !{i32 8, !"branch-target-enforcement", i32 0}
+  !7 = !{i32 8, !"sign-return-address", i32 0}
+  !8 = !{i32 8, !"sign-return-address-all", i32 0}
+  !9 = !{i32 8, !"sign-return-address-with-bkey", i32 0}
   !10 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git b19275ba870a06c5ef0428af6264ffd28c7cde9e)"}
   !11 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 4, type: !12, scopeLine: 4, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2)
   !12 = !DISubroutineType(types: !13)
Index: llvm/test/Bitcode/upgrade-branch-protection.ll
===================================================================
--- /dev/null
+++ llvm/test/Bitcode/upgrade-branch-protection.ll
@@ -0,0 +1,16 @@
+;; Test that module flags "branch-target-enforcement" and "sign-return-address"  can be upgraded to
+;; are upgraded from Error to Min.
+
+; RUN: llvm-as %s -o - | llvm-dis - | FileCheck %s
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"branch-target-enforcement", i32 1}
+!1 = !{i32 1, !"sign-return-address", i32 1}
+!2 = !{i32 1, !"sign-return-address-all", i32 1}
+!3 = !{i32 1, !"sign-return-address-with-bkey", i32 1}
+
+;CHECK: !0 = !{i32 8, !"branch-target-enforcement", i32 1}
+;CHECK: !1 = !{i32 8, !"sign-return-address", i32 1}
+;CHECK: !2 = !{i32 8, !"sign-return-address-all", i32 1}
+;CHECK: !3 = !{i32 8, !"sign-return-address-with-bkey", i32 1}
\ No newline at end of file
Index: llvm/lib/Linker/IRMover.cpp
===================================================================
--- llvm/lib/Linker/IRMover.cpp
+++ llvm/lib/Linker/IRMover.cpp
@@ -12,6 +12,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -1256,6 +1257,9 @@
   if (!SrcModFlags)
     return Error::success();
 
+  // Check for module flag for updates before do anything.
+  UpgradeModuleFlags(*SrcM);
+
   // If the destination module doesn't have module flags yet, then just copy
   // over the source module's flags.
   NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata();
@@ -1338,11 +1342,15 @@
 
     // Diagnose inconsistent merge behavior types.
     if (SrcBehaviorValue != DstBehaviorValue) {
+      bool MinAndWarn = (SrcBehaviorValue == Module::Min &&
+                         DstBehaviorValue == Module::Warning) ||
+                        (DstBehaviorValue == Module::Min &&
+                         SrcBehaviorValue == Module::Warning);
       bool MaxAndWarn = (SrcBehaviorValue == Module::Max &&
                          DstBehaviorValue == Module::Warning) ||
                         (DstBehaviorValue == Module::Max &&
                          SrcBehaviorValue == Module::Warning);
-      if (!MaxAndWarn)
+      if (!(MaxAndWarn || MinAndWarn))
         return stringErr("linking module flags '" + ID->getString() +
                          "': IDs have conflicting behaviors in '" +
                          SrcM->getModuleIdentifier() + "' and '" +
@@ -1371,6 +1379,25 @@
       emitWarning(Str);
     }
 
+    // Choose the minimum if either source or destination request Min behavior.
+    if (DstBehaviorValue == Module::Min || SrcBehaviorValue == Module::Min) {
+      ConstantInt *DstValue =
+          mdconst::extract<ConstantInt>(DstOp->getOperand(2));
+      ConstantInt *SrcValue =
+          mdconst::extract<ConstantInt>(SrcOp->getOperand(2));
+
+      // The resulting flag should have a Min behavior, and contain the minimum
+      // value from between the source and destination values.
+      Metadata *FlagOps[] = {
+          (DstBehaviorValue != Module::Min ? SrcOp : DstOp)->getOperand(0), ID,
+          (SrcValue->getZExtValue() < DstValue->getZExtValue() ? SrcOp : DstOp)
+              ->getOperand(2)};
+      MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps);
+      DstModFlags->setOperand(DstIndex, Flag);
+      Flags[ID].first = Flag;
+      continue;
+    }
+
     // Choose the maximum if either source or destination request Max behavior.
     if (DstBehaviorValue == Module::Max || SrcBehaviorValue == Module::Max) {
       ConstantInt *DstValue =
Index: llvm/lib/IR/Verifier.cpp
===================================================================
--- llvm/lib/IR/Verifier.cpp
+++ llvm/lib/IR/Verifier.cpp
@@ -1623,6 +1623,13 @@
     // These behavior types accept any value.
     break;
 
+  case Module::Min: {
+    Check(mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)),
+          "invalid value for 'min' module flag (expected constant integer)",
+          Op->getOperand(2));
+    break;
+  }
+
   case Module::Max: {
     Check(mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(2)),
           "invalid value for 'max' module flag (expected constant integer)",
Index: llvm/lib/IR/AutoUpgrade.cpp
===================================================================
--- llvm/lib/IR/AutoUpgrade.cpp
+++ llvm/lib/IR/AutoUpgrade.cpp
@@ -4388,6 +4388,24 @@
         }
       }
     }
+
+    // Upgrade branch protection and return address signing module flags. The
+    // module flag behavior for these fields were Error and now they are Min.
+    if (ID->getString() == "branch-target-enforcement" ||
+        ID->getString().startswith("sign-return-address")) {
+      if (auto *Behavior =
+              mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
+        if (Behavior->getLimitedValue() == Module::Error) {
+          Type *Int32Ty = Type::getInt32Ty(M.getContext());
+          Metadata *Ops[3] = {
+              ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Min)),
+              Op->getOperand(1), Op->getOperand(2)};
+          ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
+          Changed = true;
+        }
+      }
+    }
+
     // Upgrade Objective-C Image Info Section. Removed the whitespce in the
     // section name so that llvm-lto will not complain about mismatching
     // module flags that is functionally the same.
Index: llvm/include/llvm/IR/Module.h
===================================================================
--- llvm/include/llvm/IR/Module.h
+++ llvm/include/llvm/IR/Module.h
@@ -146,9 +146,12 @@
     /// Takes the max of the two values, which are required to be integers.
     Max = 7,
 
+    /// Takes the min of the two values, which are required to be integers.
+    Min = 8,
+
     // Markers:
     ModFlagBehaviorFirstVal = Error,
-    ModFlagBehaviorLastVal = Max
+    ModFlagBehaviorLastVal = Min
   };
 
   /// Checks if Metadata represents a valid ModFlagBehavior, and stores the
Index: clang/test/Frontend/arm-ignore-branch-protection-option.c
===================================================================
--- clang/test/Frontend/arm-ignore-branch-protection-option.c
+++ clang/test/Frontend/arm-ignore-branch-protection-option.c
@@ -15,4 +15,4 @@
 // CHECK-NOT:  attributes { {{.*}} "branch-target-enforcement"
 
 /// Check that there are branch protection module attributes despite the warning.
-// CHECK: !{i32 1, !"branch-target-enforcement", i32 1}
+// CHECK: !{i32 8, !"branch-target-enforcement", i32 1}
Index: clang/test/CodeGen/arm-branch-protection-attr-2.c
===================================================================
--- clang/test/CodeGen/arm-branch-protection-attr-2.c
+++ clang/test/CodeGen/arm-branch-protection-attr-2.c
@@ -15,19 +15,19 @@
 
 // Check module attributes
 
-// NONE:  !{i32 1, !"branch-target-enforcement", i32 0}
-// PART:  !{i32 1, !"branch-target-enforcement", i32 0}
-// ALL:   !{i32 1, !"branch-target-enforcement", i32 0}
-// BTE:   !{i32 1, !"branch-target-enforcement", i32 1}
-
-// NONE:  !{i32 1, !"sign-return-address", i32 0}
-// PART:  !{i32 1, !"sign-return-address", i32 1}
-// ALL:   !{i32 1, !"sign-return-address", i32 1}
-// BTE:   !{i32 1, !"sign-return-address", i32 0}
-
-// NONE:  !{i32 1, !"sign-return-address-all", i32 0}
-// PART:  !{i32 1, !"sign-return-address-all", i32 0}
-// ALL:   !{i32 1, !"sign-return-address-all", i32 1}
-// BTE:   !{i32 1, !"sign-return-address-all", i32 0}
+// NONE:  !{i32 8, !"branch-target-enforcement", i32 0}
+// PART:  !{i32 8, !"branch-target-enforcement", i32 0}
+// ALL:   !{i32 8, !"branch-target-enforcement", i32 0}
+// BTE:   !{i32 8, !"branch-target-enforcement", i32 1}
+
+// NONE:  !{i32 8, !"sign-return-address", i32 0}
+// PART:  !{i32 8, !"sign-return-address", i32 1}
+// ALL:   !{i32 8, !"sign-return-address", i32 1}
+// BTE:   !{i32 8, !"sign-return-address", i32 0}
+
+// NONE:  !{i32 8, !"sign-return-address-all", i32 0}
+// PART:  !{i32 8, !"sign-return-address-all", i32 0}
+// ALL:   !{i32 8, !"sign-return-address-all", i32 1}
+// BTE:   !{i32 8, !"sign-return-address-all", i32 0}
 
 void foo() {}
Index: clang/test/CodeGen/aarch64-sign-return-address.c
===================================================================
--- clang/test/CodeGen/aarch64-sign-return-address.c
+++ clang/test/CodeGen/aarch64-sign-return-address.c
@@ -19,28 +19,28 @@
 
 // Check module attributes
 
-// NONE:  !{i32 1, !"branch-target-enforcement", i32 0}
-// ALL:   !{i32 1, !"branch-target-enforcement", i32 0}
-// PART:  !{i32 1, !"branch-target-enforcement", i32 0}
-// BTE:   !{i32 1, !"branch-target-enforcement", i32 1}
-// B-KEY: !{i32 1, !"branch-target-enforcement", i32 0}
-
-// NONE:  !{i32 1, !"sign-return-address", i32 0}
-// ALL:   !{i32 1, !"sign-return-address", i32 1}
-// PART:  !{i32 1, !"sign-return-address", i32 1}
-// BTE:   !{i32 1, !"sign-return-address", i32 0}
-// B-KEY: !{i32 1, !"sign-return-address", i32 1}
-
-// NONE:  !{i32 1, !"sign-return-address-all", i32 0}
-// ALL:   !{i32 1, !"sign-return-address-all", i32 1}
-// PART:  !{i32 1, !"sign-return-address-all", i32 0}
-// BTE:   !{i32 1, !"sign-return-address-all", i32 0}
-// B-KEY: !{i32 1, !"sign-return-address-all", i32 0}
-
-// NONE:  !{i32 1, !"sign-return-address-with-bkey", i32 0}
-// ALL:   !{i32 1, !"sign-return-address-with-bkey", i32 0}
-// PART:  !{i32 1, !"sign-return-address-with-bkey", i32 0}
-// BTE:   !{i32 1, !"sign-return-address-with-bkey", i32 0}
-// B-KEY: !{i32 1, !"sign-return-address-with-bkey", i32 1}
+// NONE:  !{i32 8, !"branch-target-enforcement", i32 0}
+// ALL:   !{i32 8, !"branch-target-enforcement", i32 0}
+// PART:  !{i32 8, !"branch-target-enforcement", i32 0}
+// BTE:   !{i32 8, !"branch-target-enforcement", i32 1}
+// B-KEY: !{i32 8, !"branch-target-enforcement", i32 0}
+
+// NONE:  !{i32 8, !"sign-return-address", i32 0}
+// ALL:   !{i32 8, !"sign-return-address", i32 1}
+// PART:  !{i32 8, !"sign-return-address", i32 1}
+// BTE:   !{i32 8, !"sign-return-address", i32 0}
+// B-KEY: !{i32 8, !"sign-return-address", i32 1}
+
+// NONE:  !{i32 8, !"sign-return-address-all", i32 0}
+// ALL:   !{i32 8, !"sign-return-address-all", i32 1}
+// PART:  !{i32 8, !"sign-return-address-all", i32 0}
+// BTE:   !{i32 8, !"sign-return-address-all", i32 0}
+// B-KEY: !{i32 8, !"sign-return-address-all", i32 0}
+
+// NONE:  !{i32 8, !"sign-return-address-with-bkey", i32 0}
+// ALL:   !{i32 8, !"sign-return-address-with-bkey", i32 0}
+// PART:  !{i32 8, !"sign-return-address-with-bkey", i32 0}
+// BTE:   !{i32 8, !"sign-return-address-with-bkey", i32 0}
+// B-KEY: !{i32 8, !"sign-return-address-with-bkey", i32 1}
 
 void foo() {}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -729,7 +729,10 @@
   // attributes, but we use module metadata to emit build attributes. This is
   // needed for LTO, where the function attributes are inside bitcode
   // serialised into a global variable by the time build attributes are
-  // emitted, so we can't access them.
+  // emitted, so we can't access them. LTO objects could be compiled with
+  // different flags therefore module flags are set to "Min" behavior to achieve
+  // the same end result of the normal build where e.g BTI is off if any object
+  // doesn't support it.
   if (Context.getTargetInfo().hasFeature("ptrauth") &&
       LangOpts.getSignReturnAddressScope() !=
           LangOptions::SignReturnAddressScopeKind::None)
@@ -743,16 +746,16 @@
       Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb ||
       Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::aarch64_32 ||
       Arch == llvm::Triple::aarch64_be) {
-    getModule().addModuleFlag(llvm::Module::Error, "branch-target-enforcement",
+    getModule().addModuleFlag(llvm::Module::Min, "branch-target-enforcement",
                               LangOpts.BranchTargetEnforcement);
 
-    getModule().addModuleFlag(llvm::Module::Error, "sign-return-address",
+    getModule().addModuleFlag(llvm::Module::Min, "sign-return-address",
                               LangOpts.hasSignReturnAddress());
 
-    getModule().addModuleFlag(llvm::Module::Error, "sign-return-address-all",
+    getModule().addModuleFlag(llvm::Module::Min, "sign-return-address-all",
                               LangOpts.isSignReturnAddressScopeAll());
 
-    getModule().addModuleFlag(llvm::Module::Error,
+    getModule().addModuleFlag(llvm::Module::Min,
                               "sign-return-address-with-bkey",
                               !LangOpts.isSignReturnAddressWithAKey());
   }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to