Using Max for both "PIC Level" and "PIE Level" is inconsistent. PIC imposes less
restriction while PIE imposes more restriction. The result generally
picks the more restrictive behavior: Min for PIC.
This choice matches `ld -r`: a non-pic object and a pic object merge into a
result which should be treated as non-pic.
To allow linking "PIC Level" using Error/Max from old bitcode files, upgrade
Error/Max to Min.
Reviewed By: tejohnson
Differential Revision: https://reviews.llvm.org/D130531
// RUN: %clang_cc1 -emit-llvm -pic-level 1 -pic-is-pie %s -o - | FileCheck %s -check-prefix=CHECK-SMALLPIC -check-prefix=CHECK-SMALLPIE
// CHECK-BIGPIC: !llvm.module.flags = !{{{.*}}}
-// CHECK-BIGPIC: !{{[0-9]+}} = !{i32 7, !"PIC Level", i32 2}
+// CHECK-BIGPIC: ![[#]] = !{i32 8, !"PIC Level", i32 2}
// CHECK-SMALLPIC: !llvm.module.flags = !{{{.*}}}
-// CHECK-SMALLPIC: !{{[0-9]+}} = !{i32 7, !"PIC Level", i32 1}
+// CHECK-SMALLPIC: ![[#]] = !{i32 8, !"PIC Level", i32 1}
// CHECK-NOPIE-NOT: PIE Level
-// CHECK-BIGPIE: !{{[0-9]+}} = !{i32 7, !"PIE Level", i32 2}
-// CHECK-SMALLPIE: !{{[0-9]+}} = !{i32 7, !"PIE Level", i32 1}
+// CHECK-BIGPIE: ![[#]] = !{i32 7, !"PIE Level", i32 2}
+// CHECK-SMALLPIE: ![[#]] = !{i32 7, !"PIE Level", i32 1}
MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
if (!ID)
continue;
+ auto SetBehavior = [&](Module::ModFlagBehavior B) {
+ Metadata *Ops[3] = {ConstantAsMetadata::get(ConstantInt::get(
+ Type::getInt32Ty(M.getContext()), B)),
+ MDString::get(M.getContext(), ID->getString()),
+ Op->getOperand(2)};
+ ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
+ Changed = true;
+ };
+
if (ID->getString() == "Objective-C Image Info Version")
HasObjCFlag = true;
if (ID->getString() == "Objective-C Class Properties")
HasClassProperties = true;
- // Upgrade PIC/PIE Module Flags. The module flag behavior for these two
- // field was Error and now they are Max.
- if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") {
+ // Upgrade PIC from Error/Max to Min.
+ if (ID->getString() == "PIC Level") {
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::Max)),
- MDString::get(M.getContext(), ID->getString()),
- Op->getOperand(2)};
- ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
- Changed = true;
- }
+ uint64_t V = Behavior->getLimitedValue();
+ if (V == Module::Error || V == Module::Max)
+ SetBehavior(Module::Min);
}
}
+ // Upgrade "PIE Level" from Error to Max.
+ if (ID->getString() == "PIE Level")
+ if (auto *Behavior =
+ mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0)))
+ if (Behavior->getLimitedValue() == Module::Error)
+ SetBehavior(Module::Max);
// Upgrade branch protection and return address signing module flags. The
// module flag behavior for these fields were Error and now they are Min.
}
void Module::setPICLevel(PICLevel::Level PL) {
- addModuleFlag(ModFlagBehavior::Max, "PIC Level", PL);
+ // The merge result of a non-PIC object and a PIC object can only be reliably
+ // used as a non-PIC object, so use the Min merge behavior.
+ addModuleFlag(ModFlagBehavior::Min, "PIC Level", PL);
}
PIELevel::Level Module::getPIELevel() const {
!2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
!3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA, __objc_imageinfo, regular, no_dead_strip"}
-; CHECK: !0 = !{i32 7, !"PIC Level", i32 1}
+; CHECK: !0 = !{i32 8, !"PIC Level", i32 1}
; CHECK: !1 = !{i32 7, !"PIE Level", i32 1}
; CHECK: !2 = !{i32 1, !"Objective-C Image Info Version", i32 0}
; CHECK: !3 = !{i32 1, !"Objective-C Image Info Section", !"__DATA,__objc_imageinfo,regular,no_dead_strip"}
--- /dev/null
+; RUN: llvm-as < %s | llvm-dis | FileCheck %s
+; RUN: verify-uselistorder < %s
+
+!llvm.module.flags = !{!0}
+
+; CHECK: !0 = !{i32 8, !"PIC Level", i32 1}
+
+!0 = !{i32 7, !"PIC Level", i32 1}
-!0 = !{ i32 7, !"PIC Level", i32 2 }
+!0 = !{ i32 8, !"PIC Level", i32 2 }
!1 = !{ i32 7, !"PIE Level", i32 2 }
!llvm.module.flags = !{!0, !1}
!llvm.module.flags = !{!0}
; CHECK: !llvm.module.flags = !{!0}
-; CHECK: !0 = !{i32 7, !"PIC Level", i32 1}
+; CHECK: !0 = !{i32 8, !"PIC Level", i32 1}
; test linking modules with two different PIC and PIE levels
-!0 = !{ i32 7, !"PIC Level", i32 1 }
+!0 = !{ i32 8, !"PIC Level", i32 1 }
!1 = !{ i32 7, !"PIE Level", i32 1 }
!llvm.module.flags = !{!0, !1}
-; CHECK: !0 = !{i32 7, !"PIC Level", i32 2}
+; CHECK: !0 = !{i32 8, !"PIC Level", i32 1}
; CHECK: !1 = !{i32 7, !"PIE Level", i32 2}
!7 = !{i32 7, !"Dwarf Version", i32 5}
!8 = !{i32 2, !"Debug Info Version", i32 3}
!9 = !{i32 1, !"wchar_size", i32 4}
-!10 = !{i32 7, !"PIC Level", i32 2}
+!10 = !{i32 8, !"PIC Level", i32 2}
!11 = !{i32 7, !"PIE Level", i32 2}
!12 = !{i32 7, !"uwtable", i32 2}
!13 = !{i32 7, !"frame-pointer", i32 2}
; CHECK: [[META7:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 5}
; CHECK: [[META8:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
; CHECK: [[META9:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
-; CHECK: [[META10:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK: [[META10:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK: [[META11:![0-9]+]] = !{i32 7, !"PIE Level", i32 2}
; CHECK: [[META12:![0-9]+]] = !{i32 7, !"uwtable", i32 2}
; CHECK: [[META13:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 7, !"openmp", i32 50}
!3 = !{i32 7, !"openmp-device", i32 50}
-!4 = !{i32 7, !"PIC Level", i32 2}
+!4 = !{i32 8, !"PIC Level", i32 2}
!5 = !{i32 7, !"frame-pointer", i32 2}
!6 = !{i32 7, !"Dwarf Version", i32 2}
!7 = !{i32 2, !"Debug Info Version", i32 3}
; CHECK: [[META1:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; CHECK: [[META2:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; CHECK: [[META3:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK: [[META4:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK: [[META4:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK: [[META5:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"Dwarf Version", i32 2}
; CHECK: [[META7:![0-9]+]] = !{i32 2, !"Debug Info Version", i32 3}
!12 = !{i32 1, !"wchar_size", i32 4}
!13 = !{i32 7, !"openmp", i32 50}
!14 = !{i32 7, !"openmp-device", i32 50}
-!15 = !{i32 7, !"PIC Level", i32 2}
+!15 = !{i32 8, !"PIC Level", i32 2}
!16 = !{i32 7, !"frame-pointer", i32 2}
!17 = !{!"clang version 14.0.0"}
!18 = !{!19, !19, i64 0}
; AMDGPU: [[META12:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; AMDGPU: [[META13:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; AMDGPU: [[META14:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; AMDGPU: [[META15:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; AMDGPU: [[META15:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; AMDGPU: [[META16:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; AMDGPU: [[META17:![0-9]+]] = !{!"clang version 14.0.0"}
; AMDGPU: [[TBAA18]] = !{!19, !19, i64 0}
; NVPTX: [[META12:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; NVPTX: [[META13:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; NVPTX: [[META14:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; NVPTX: [[META15:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; NVPTX: [[META15:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; NVPTX: [[META16:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; NVPTX: [[META17:![0-9]+]] = !{!"clang version 14.0.0"}
; NVPTX: [[TBAA18]] = !{!19, !19, i64 0}
; AMDGPU-DISABLED: [[META12:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; AMDGPU-DISABLED: [[META13:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; AMDGPU-DISABLED: [[META14:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; AMDGPU-DISABLED: [[META15:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; AMDGPU-DISABLED: [[META15:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; AMDGPU-DISABLED: [[META16:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; AMDGPU-DISABLED: [[META17:![0-9]+]] = !{!"clang version 14.0.0"}
; AMDGPU-DISABLED: [[TBAA18]] = !{!19, !19, i64 0}
; NVPTX-DISABLED: [[META12:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; NVPTX-DISABLED: [[META13:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; NVPTX-DISABLED: [[META14:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; NVPTX-DISABLED: [[META15:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; NVPTX-DISABLED: [[META15:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; NVPTX-DISABLED: [[META16:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; NVPTX-DISABLED: [[META17:![0-9]+]] = !{!"clang version 14.0.0"}
; NVPTX-DISABLED: [[TBAA18]] = !{!19, !19, i64 0}
!2 = !{i32 1, !"wchar_size", i32 4}
!3 = !{i32 7, !"openmp", i32 50}
!4 = !{i32 7, !"openmp-device", i32 50}
-!5 = !{i32 7, !"PIC Level", i32 2}
+!5 = !{i32 8, !"PIC Level", i32 2}
!6 = !{i32 7, !"frame-pointer", i32 2}
!7 = !{!"clang version 14.0.0"}
!8 = !{!9, !9, i64 0}
; CHECK: [[META2:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; CHECK: [[META3:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; CHECK: [[META4:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK: [[META5:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK: [[META5:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; CHECK: [[META7:![0-9]+]] = !{!"clang version 14.0.0"}
; CHECK: [[TBAA8]] = !{!9, !9, i64 0}
!2 = !{i32 1, !"wchar_size", i32 4}
!3 = !{i32 7, !"openmp", i32 50}
!4 = !{i32 7, !"openmp-device", i32 50}
-!5 = !{i32 7, !"PIC Level", i32 2}
+!5 = !{i32 8, !"PIC Level", i32 2}
!6 = !{i32 7, !"frame-pointer", i32 2}
!7 = !{!"clang version 14.0.0"}
!8 = !{!9}
; CHECK: [[META2:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; CHECK: [[META3:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; CHECK: [[META4:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK: [[META5:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK: [[META5:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; CHECK: [[META7:![0-9]+]] = !{!"clang version 14.0.0"}
; CHECK: [[META8:![0-9]+]] = !{!9}
; CHECK-DISABLED: [[META2:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; CHECK-DISABLED: [[META3:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; CHECK-DISABLED: [[META4:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK-DISABLED: [[META5:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK-DISABLED: [[META5:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK-DISABLED: [[META6:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; CHECK-DISABLED: [[META7:![0-9]+]] = !{!"clang version 14.0.0"}
; CHECK-DISABLED: [[META8:![0-9]+]] = !{!9}
!4 = !{i32 1, !"wchar_size", i32 4}
!5 = !{i32 7, !"openmp", i32 50}
!6 = !{i32 7, !"openmp-device", i32 50}
-!7 = !{i32 7, !"PIC Level", i32 2}
+!7 = !{i32 8, !"PIC Level", i32 2}
!8 = !{i32 7, !"frame-pointer", i32 2}
!9 = !{!"clang version 14.0.0"}
;.
; CHECK: [[META4:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
; CHECK: [[META5:![0-9]+]] = !{i32 7, !"openmp", i32 50}
; CHECK: [[META6:![0-9]+]] = !{i32 7, !"openmp-device", i32 50}
-; CHECK: [[META7:![0-9]+]] = !{i32 7, !"PIC Level", i32 2}
+; CHECK: [[META7:![0-9]+]] = !{i32 8, !"PIC Level", i32 2}
; CHECK: [[META8:![0-9]+]] = !{i32 7, !"frame-pointer", i32 2}
; CHECK: [[META9:![0-9]+]] = !{!"clang version 14.0.0"}
;.