diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 3b7fe7fa226607..43d4496571be50 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3850,6 +3850,12 @@ bool InstCombinerImpl::transformConstExprCastCall(CallBase &Call) { if (Callee->hasFnAttribute("thunk")) return false; + // If this is a call to a naked function, the assembly might be + // using an argument, or otherwise rely on the frame layout, + // the function prototype will mismatch. + if (Callee->hasFnAttribute(Attribute::Naked)) + return false; + // If this is a musttail call, the callee's prototype must match the caller's // prototype with the exception of pointee types. The code below doesn't // implement that, so we can't do this transform. diff --git a/llvm/test/Transforms/InstCombine/call-cast-attrs.ll b/llvm/test/Transforms/InstCombine/call-cast-attrs.ll index 0b4ce1fa293f85..bb122b0e2c4aab 100644 --- a/llvm/test/Transforms/InstCombine/call-cast-attrs.ll +++ b/llvm/test/Transforms/InstCombine/call-cast-attrs.ll @@ -16,6 +16,11 @@ define void @d(i32 %x, ...) { ret void } +define void @naked_func() naked { + tail call void asm sideeffect "mov r1, r0", ""() + unreachable +} + define void @g(ptr %y) { call i32 @b(i32 zeroext 0) call void @c(ptr %y) @@ -23,6 +28,7 @@ define void @g(ptr %y) { call void @d(i32 0, ptr sret(i32) %y) call void @d(i32 0, ptr nocapture %y) call void @d(ptr nocapture noundef %y) + call void @naked_func(i32 1) ret void } ; CHECK-LABEL: define void @g(ptr %y) @@ -34,3 +40,4 @@ define void @g(ptr %y) { ; CHECK32: %2 = ptrtoint ptr %y to i32 ; CHECK32: call void (i32, ...) @d(i32 noundef %2) ; CHECK64: call void @d(ptr nocapture noundef %y) +; CHECK: call void @naked_func(i32 1) diff --git a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll index c560940835279a..3e1f8b97e98b82 100644 --- a/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll +++ b/llvm/test/Transforms/LowerTypeTests/cfi-unwind-direct-call.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --include-generated-funcs --version 2 +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-attributes --include-generated-funcs --version 4 ; RUN: opt < %s -passes='lowertypetests,default' -S | FileCheck %s ; This IR is based of the following C++ @@ -156,38 +156,38 @@ attributes #8 = { noreturn nounwind } !13 = !{} !14 = !{!"branch_weights", i32 1048575, i32 1} ; CHECK: Function Attrs: minsize mustprogress optsize -; CHECK-LABEL: define dso_local void @_Z7throw_ei -; CHECK-SAME: (i32 noundef [[NUM:%.*]]) #[[ATTR0:[0-9]+]] !type !4 !type !5 !type !6 { +; CHECK-LABEL: define dso_local void @_Z7throw_ei( +; CHECK-SAME: i32 noundef [[NUM:%.*]]) #[[ATTR0:[0-9]+]] !type [[META4:![0-9]+]] !type [[META5:![0-9]+]] !type [[META6:![0-9]+]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[NUM]], 0 ; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] ; CHECK: if.then: -; CHECK-NEXT: [[EXCEPTION:%.*]] = tail call ptr @__cxa_allocate_exception(i64 4) #[[ATTR5:[0-9]+]] +; CHECK-NEXT: [[EXCEPTION:%.*]] = tail call ptr @__cxa_allocate_exception(i64 4) #[[ATTR6:[0-9]+]] ; CHECK-NEXT: store i32 20, ptr [[EXCEPTION]], align 16, !tbaa [[TBAA7:![0-9]+]] -; CHECK-NEXT: tail call void @__cxa_throw(ptr nonnull [[EXCEPTION]], ptr nonnull @_ZTIi, ptr null) #[[ATTR6:[0-9]+]] +; CHECK-NEXT: tail call void @__cxa_throw(ptr nonnull [[EXCEPTION]], ptr nonnull @_ZTIi, ptr null) #[[ATTR7:[0-9]+]] ; CHECK-NEXT: unreachable ; CHECK: if.end: ; CHECK-NEXT: ret void ; ; ; CHECK: Function Attrs: minsize mustprogress optsize -; CHECK-LABEL: define dso_local void @_Z10call_catchi -; CHECK-SAME: (i32 noundef [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] personality ptr @__gxx_personality_v0 !type !4 !type !5 !type !6 { +; CHECK-LABEL: define dso_local void @_Z10call_catchi( +; CHECK-SAME: i32 noundef [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] personality ptr @__gxx_personality_v0 !type [[META4]] !type [[META5]] !type [[META6]] { ; CHECK-NEXT: entry: ; CHECK-NEXT: store ptr @_Z7throw_ei.cfi_jt, ptr @catch_ptr, align 8, !tbaa [[TBAA11:![0-9]+]] -; CHECK-NEXT: invoke void @_Z7throw_ei.cfi_jt() #[[ATTR7:[0-9]+]] -; CHECK-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]] +; CHECK-NEXT: invoke void @_Z7throw_ei.cfi_jt(i32 noundef [[NUM]]) #[[ATTR8:[0-9]+]] +; CHECK-NEXT: to label [[TRY_CONT:%.*]] unwind label [[LPAD:%.*]], !callees [[META13:![0-9]+]] ; CHECK: lpad: ; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } -; CHECK-NEXT: catch ptr @_ZTIi +; CHECK-NEXT: catch ptr @_ZTIi ; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1 -; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #[[ATTR5]] +; CHECK-NEXT: [[TMP2:%.*]] = tail call i32 @llvm.eh.typeid.for(ptr nonnull @_ZTIi) #[[ATTR6]] ; CHECK-NEXT: [[MATCHES:%.*]] = icmp eq i32 [[TMP1]], [[TMP2]] ; CHECK-NEXT: br i1 [[MATCHES]], label [[CATCH:%.*]], label [[EH_RESUME:%.*]] ; CHECK: catch: ; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 -; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR5]] -; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR5]] +; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR6]] +; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR6]] ; CHECK-NEXT: br label [[TRY_CONT]] ; CHECK: try.cont: ; CHECK-NEXT: ret void @@ -196,33 +196,46 @@ attributes #8 = { noreturn nounwind } ; ; ; CHECK: Function Attrs: minsize optsize -; CHECK-LABEL: define weak_odr hidden void @__cfi_check_fail -; CHECK-SAME: (ptr noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { +; CHECK-LABEL: define weak_odr hidden void @__cfi_check_fail( +; CHECK-SAME: ptr noundef [[TMP0:%.*]], ptr noundef [[TMP1:%.*]]) #[[ATTR2:[0-9]+]] { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq ptr [[TMP0]], null, !nosanitize !13 -; CHECK-NEXT: br i1 [[DOTNOT]], label [[TRAP:%.*]], label [[CONT:%.*]], !nosanitize !13 +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq ptr [[TMP0]], null, !nosanitize [[META14:![0-9]+]] +; CHECK-NEXT: br i1 [[DOTNOT]], label [[TRAP:%.*]], label [[CONT:%.*]], !nosanitize [[META14]] ; CHECK: trap: -; CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR8:[0-9]+]], !nosanitize !13 -; CHECK-NEXT: unreachable, !nosanitize !13 +; CHECK-NEXT: tail call void @llvm.ubsantrap(i8 2) #[[ATTR9:[0-9]+]], !nosanitize [[META14]] +; CHECK-NEXT: unreachable, !nosanitize [[META14]] ; CHECK: cont: -; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP0]], align 4, !nosanitize !13 +; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP0]], align 4, !nosanitize [[META14]] ; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i8 [[TMP2]], 5 ; CHECK-NEXT: br i1 [[SWITCH]], label [[TRAP]], label [[CONT6:%.*]] ; CHECK: cont6: -; CHECK-NEXT: ret void, !nosanitize !13 +; CHECK-NEXT: ret void, !nosanitize [[META14]] ; ; -; CHECK-LABEL: define weak void @__cfi_check -; CHECK-SAME: (i64 [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) local_unnamed_addr { +; CHECK-LABEL: define weak void @__cfi_check( +; CHECK-SAME: i64 [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) local_unnamed_addr { ; CHECK-NEXT: entry: ; CHECK-NEXT: tail call void @llvm.trap() ; CHECK-NEXT: unreachable ; ; ; CHECK: Function Attrs: naked nocf_check noinline -; CHECK-LABEL: define internal void @_Z7throw_ei.cfi_jt -; CHECK-SAME: () #[[ATTR4:[0-9]+]] align 8 { +; CHECK-LABEL: define internal void @_Z7throw_ei.cfi_jt( +; CHECK-SAME: ) #[[ATTR5:[0-9]+]] align 8 { ; CHECK-NEXT: entry: -; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z7throw_ei) #[[ATTR5]] +; CHECK-NEXT: tail call void asm sideeffect "jmp ${0:c}@plt\0Aint3\0Aint3\0Aint3\0A", "s"(ptr nonnull @_Z7throw_ei) #[[ATTR6]] ; CHECK-NEXT: unreachable ; +;. +; CHECK: [[META4]] = !{i64 0, !"_ZTSFviE"} +; CHECK: [[META5]] = !{i64 0, !"_ZTSFviE.generalized"} +; CHECK: [[META6]] = !{i64 0, i64 -8738933900360652027} +; CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0} +; CHECK: [[META8]] = !{!"int", [[META9:![0-9]+]], i64 0} +; CHECK: [[META9]] = !{!"omnipotent char", [[META10:![0-9]+]], i64 0} +; CHECK: [[META10]] = !{!"Simple C++ TBAA"} +; CHECK: [[TBAA11]] = !{[[META12:![0-9]+]], [[META12]], i64 0} +; CHECK: [[META12]] = !{!"any pointer", [[META9]], i64 0} +; CHECK: [[META13]] = !{ptr @_Z7throw_ei.cfi_jt} +; CHECK: [[META14]] = !{} +;.