Index: lib/IR/ConstantFold.cpp =================================================================== --- lib/IR/ConstantFold.cpp +++ lib/IR/ConstantFold.cpp @@ -1077,10 +1077,11 @@ isa(CE1->getOperand(0))) { GlobalValue *GV = cast(CE1->getOperand(0)); - // Functions are at least 4-byte aligned. unsigned GVAlign = GV->getAlignment(); - if (isa(GV)) - GVAlign = std::max(GVAlign, 4U); + + // If alignment isn't specified on functions don't assume it. + if (isa(GV) && GVAlign == 0) + return nullptr; if (GVAlign > 1) { unsigned DstWidth = CI2->getType()->getBitWidth(); Index: test/Analysis/ConstantFolding/func-and-folding.ll =================================================================== --- /dev/null +++ test/Analysis/ConstantFolding/func-and-folding.ll @@ -0,0 +1,35 @@ +; RUN: opt < %s -constprop -S -o - | FileCheck %s + +; Function Attrs: minsize norecurse nounwind optsize readnone +define dso_local void @foo1() #0 { +entry: + ret void +} + +; Function Attrs: minsize norecurse nounwind optsize readnone +define dso_local void @foo2() #0 { +entry: + ret void +} + +; Function Attrs: minsize norecurse nounwind optsize readnone +define dso_local void @foo3() align 4 { +entry: + ret void +} + +; Function Attrs: minsize nounwind optsize +define dso_local i32 @main() local_unnamed_addr #1 { +entry: +; CHECK: ptrtoint + %call = tail call i32 bitcast (i32 (...)* @process to i32 (i32)*)(i32 and (i32 ptrtoint (void ()* @foo1 to i32), i32 2)) #3 +; CHECK-NEXT: ptrtoint + %call2 = tail call i32 bitcast (i32 (...)* @process to i32 (i32)*)(i32 and (i32 ptrtoint (void ()* @foo2 to i32), i32 2)) #3 +; CHECK-NOT: ptrtoint + %call3 = tail call i32 bitcast (i32 (...)* @process to i32 (i32)*)(i32 and (i32 ptrtoint (void ()* @foo3 to i32), i32 2)) #3 + ret i32 0 +} + +; Function Attrs: minsize optsize +declare dso_local i32 @process(...) local_unnamed_addr #2 + Index: test/Assembler/2004-03-07-FunctionAddressAlignment.ll =================================================================== --- test/Assembler/2004-03-07-FunctionAddressAlignment.ll +++ test/Assembler/2004-03-07-FunctionAddressAlignment.ll @@ -3,11 +3,11 @@ ; All of these should be eliminable -define i32 @foo() { +define i32 @foo() align 4 { ret i32 and (i32 ptrtoint (i32()* @foo to i32), i32 1) } -define i32 @foo2() { +define i32 @foo2() align 4 { ret i32 and (i32 1, i32 ptrtoint (i32()* @foo2 to i32)) }