diff options
-rw-r--r-- | llvm/include/llvm/Bitcode/LLVMBitCodes.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Attributes.td | 3 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/CodeExtractor.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 7 | ||||
-rw-r--r-- | llvm/test/Transforms/SimplifyCFG/opt-for-fuzzing.ll | 49 |
13 files changed, 76 insertions, 0 deletions
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index 1519536902d..f3500e13c5f 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -588,6 +588,7 @@ enum AttributeKindCodes { ATTR_KIND_STRICT_FP = 54, ATTR_KIND_SANITIZE_HWADDRESS = 55, ATTR_KIND_NOCF_CHECK = 56, + ATTR_KIND_OPT_FOR_FUZZING = 57, }; enum ComdatSelectionKindCodes { diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td index 5dd4f3fa634..554f0df768a 100644 --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -112,6 +112,9 @@ def NoCfCheck : EnumAttr<"nocf_check">; /// Function doesn't unwind stack. def NoUnwind : EnumAttr<"nounwind">; +/// Select optimizations for best fuzzing signal. +def OptForFuzzing : EnumAttr<"optforfuzzing">; + /// opt_size. def OptimizeForSize : EnumAttr<"optsize">; diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index e3157603203..645d9aae6ea 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -650,6 +650,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(noreturn); KEYWORD(nocf_check); KEYWORD(nounwind); + KEYWORD(optforfuzzing); KEYWORD(optnone); KEYWORD(optsize); KEYWORD(readnone); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 1c607de4427..d59b21dd4c7 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1134,6 +1134,8 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, case lltok::kw_nocf_check: B.addAttribute(Attribute::NoCfCheck); break; case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break; case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break; + case lltok::kw_optforfuzzing: + B.addAttribute(Attribute::OptForFuzzing); break; case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break; case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break; case lltok::kw_readnone: B.addAttribute(Attribute::ReadNone); break; @@ -1471,6 +1473,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { case lltok::kw_noreturn: case lltok::kw_nocf_check: case lltok::kw_nounwind: + case lltok::kw_optforfuzzing: case lltok::kw_optnone: case lltok::kw_optsize: case lltok::kw_returns_twice: @@ -1565,6 +1568,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { case lltok::kw_noreturn: case lltok::kw_nocf_check: case lltok::kw_nounwind: + case lltok::kw_optforfuzzing: case lltok::kw_optnone: case lltok::kw_optsize: case lltok::kw_returns_twice: diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 3ef44d48ec9..d24f74a145c 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -201,6 +201,7 @@ enum Kind { kw_noreturn, kw_nocf_check, kw_nounwind, + kw_optforfuzzing, kw_optnone, kw_optsize, kw_readnone, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 74b57a86b8b..5867db46272 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1161,6 +1161,7 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::StrictFP: return 1ULL << 55; case Attribute::SanitizeHWAddress: return 1ULL << 56; case Attribute::NoCfCheck: return 1ULL << 57; + case Attribute::OptForFuzzing: return 1ULL << 58; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1343,6 +1344,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::NoCfCheck; case bitc::ATTR_KIND_NO_UNWIND: return Attribute::NoUnwind; + case bitc::ATTR_KIND_OPT_FOR_FUZZING: + return Attribute::OptForFuzzing; case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE: return Attribute::OptimizeForSize; case bitc::ATTR_KIND_OPTIMIZE_NONE: diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index d82101b1413..b43a26fcc04 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -642,6 +642,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { return bitc::ATTR_KIND_NOCF_CHECK; case Attribute::NoUnwind: return bitc::ATTR_KIND_NO_UNWIND; + case Attribute::OptForFuzzing: + return bitc::ATTR_KIND_OPT_FOR_FUZZING; case Attribute::OptimizeForSize: return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE; case Attribute::OptimizeNone: diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 0aea24f22c0..1a060ba2768 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -305,6 +305,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "norecurse"; if (hasAttribute(Attribute::NoUnwind)) return "nounwind"; + if (hasAttribute(Attribute::OptForFuzzing)) + return "optforfuzzing"; if (hasAttribute(Attribute::OptimizeNone)) return "optnone"; if (hasAttribute(Attribute::OptimizeForSize)) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index aec5c682296..4cb16613046 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1430,6 +1430,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) { case Attribute::Builtin: case Attribute::NoBuiltin: case Attribute::Cold: + case Attribute::OptForFuzzing: case Attribute::OptimizeNone: case Attribute::JumpTable: case Attribute::Convergent: diff --git a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp index d10b4f4aaeb..f7cdd416fd8 100644 --- a/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp @@ -45,6 +45,7 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) { .Case("nocf_check", Attribute::NoCfCheck) .Case("norecurse", Attribute::NoRecurse) .Case("nounwind", Attribute::NoUnwind) + .Case("optforfuzzing", Attribute::OptForFuzzing) .Case("optnone", Attribute::OptimizeNone) .Case("optsize", Attribute::OptimizeForSize) .Case("readnone", Attribute::ReadNone) diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp index ef39f21632c..d87eccf4c27 100644 --- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -684,6 +684,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs, case Attribute::NonLazyBind: case Attribute::NoRedZone: case Attribute::NoUnwind: + case Attribute::OptForFuzzing: case Attribute::OptimizeNone: case Attribute::OptimizeForSize: case Attribute::SafeStack: diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 685fdb7ec63..5dc9d2c3b71 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -2273,6 +2273,10 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI, // dependence information for this check, but simplifycfg can't keep it up // to date, and this catches most of the cases we care about anyway. BasicBlock *BB = PN->getParent(); + const Function *Fn = BB->getParent(); + if (Fn && Fn->hasFnAttribute(Attribute::OptForFuzzing)) + return false; + BasicBlock *IfTrue, *IfFalse; Value *IfCond = GetIfCondition(BB, IfTrue, IfFalse); if (!IfCond || @@ -5799,6 +5803,9 @@ static BasicBlock *allPredecessorsComeFromSameSource(BasicBlock *BB) { bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) { BasicBlock *BB = BI->getParent(); + const Function *Fn = BB->getParent(); + if (Fn && Fn->hasFnAttribute(Attribute::OptForFuzzing)) + return false; // Conditional branch if (isValueEqualityComparison(BI)) { diff --git a/llvm/test/Transforms/SimplifyCFG/opt-for-fuzzing.ll b/llvm/test/Transforms/SimplifyCFG/opt-for-fuzzing.ll new file mode 100644 index 00000000000..429f4a3f854 --- /dev/null +++ b/llvm/test/Transforms/SimplifyCFG/opt-for-fuzzing.ll @@ -0,0 +1,49 @@ +; RUN: opt < %s -simplifycfg -S | FileCheck %s + +define i32 @foo(i32 %x) optforfuzzing { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + %0 = load i32, i32* %x.addr, align 4 + %cmp = icmp sgt i32 %0, 16 + br i1 %cmp, label %land.rhs, label %land.end + +land.rhs: + %1 = load i32, i32* %x.addr, align 4 + %cmp1 = icmp slt i32 %1, 32 + br label %land.end + +land.end: + %2 = phi i1 [ false, %entry ], [ %cmp1, %land.rhs ] + %conv = zext i1 %2 to i32 + ret i32 %conv + +; CHECK-LABEL: define i32 @foo(i32 %x) +; CHECK: br i1 %cmp, label %land.rhs, label %land.end +; CHECK-LABEL: land.rhs: +; CHECK: br label %land.end +; CHECK-LABEL: land.end: +; CHECK: phi {{.*}} %entry {{.*}} %land.rhs +} + +define i32 @bar(i32 %x) { +entry: + %x.addr = alloca i32, align 4 + store i32 %x, i32* %x.addr, align 4 + %0 = load i32, i32* %x.addr, align 4 + %cmp = icmp sgt i32 %0, 16 + br i1 %cmp, label %land.rhs, label %land.end + +land.rhs: + %1 = load i32, i32* %x.addr, align 4 + %cmp1 = icmp slt i32 %1, 32 + br label %land.end + +land.end: + %2 = phi i1 [ false, %entry ], [ %cmp1, %land.rhs ] + %conv = zext i1 %2 to i32 + ret i32 %conv + +; CHECK-LABEL: define i32 @bar(i32 %x) +; CHECK-NOT: br +} |