Skip to content

Commit c58232c

Browse files
committed
Address review comments
- Add IRBuilder::resetModeToStrictFP instead of adding extra argument to setIsFPConstrained. - Change wording in the Release Notes. - Modify printing MemoryEffects of FP operation. - Fix IRBuilder::CreateCall. - Clean up unit test.
1 parent 131f152 commit c58232c

File tree

15 files changed

+153
-94
lines changed

15 files changed

+153
-94
lines changed

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
10921092
if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) ||
10931093
(!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
10941094
RM != llvm::RoundingMode::NearestTiesToEven))) {
1095-
Builder.setIsFPConstrained(true, false);
1095+
Builder.setIsFPConstrained(true);
10961096
Fn->addFnAttr(llvm::Attribute::StrictFP);
10971097
}
10981098

llvm/docs/ReleaseNotes.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ Makes programs 10x faster by doing Special New Thing.
5656
Changes to the LLVM IR
5757
----------------------
5858

59-
* Floating-point operand bundles have been added.
59+
* Calls to floating-point intrinsics can have operand bundles "fp.round" and
60+
"fp.except", which specify effective rounding mode and exception behavior.
6061

6162
Changes to LLVM infrastructure
6263
------------------------------

llvm/include/llvm/IR/FPEnv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ LLVM_ABI std::optional<StringRef>
8181
std::optional<StringRef>
8282
convertExceptionBehaviorToBundle(fp::ExceptionBehavior);
8383

84+
inline raw_ostream &operator<<(raw_ostream &OS, fp::ExceptionBehavior EB) {
85+
OS << convertExceptionBehaviorToBundle(EB).value_or("invalid");
86+
return OS;
87+
}
88+
8489
/// Returns true if the exception handling behavior and rounding mode
8590
/// match what is used in the default floating point environment.
8691
inline bool isDefaultFPEnvironment(fp::ExceptionBehavior EB, RoundingMode RM) {

llvm/include/llvm/IR/IRBuilder.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,17 +348,19 @@ class IRBuilderBase {
348348
/// enabled the CreateF<op>() calls instead create constrained
349349
/// floating point intrinsic calls. Fast math flags are unaffected
350350
/// by this setting.
351-
void setIsFPConstrained(bool IsCon, bool AndReset = true) {
352-
if (AndReset) {
353-
if (IsCon) {
354-
setDefaultConstrainedRounding(RoundingMode::Dynamic);
355-
setDefaultConstrainedExcept(fp::ebStrict);
356-
} else {
357-
setDefaultConstrainedRounding(RoundingMode::NearestTiesToEven);
358-
setDefaultConstrainedExcept(fp::ebIgnore);
359-
}
351+
void setIsFPConstrained(bool IsCon) { IsFPConstrained = IsCon; }
352+
353+
/// Enable/Disable use of constrained floating point math and reset FP options
354+
/// according to the selected mode.
355+
void resetModeToStrictFP(bool IsCon) {
356+
if (IsCon) {
357+
setDefaultConstrainedRounding(RoundingMode::Dynamic);
358+
setDefaultConstrainedExcept(fp::ebStrict);
359+
} else {
360+
setDefaultConstrainedRounding(RoundingMode::NearestTiesToEven);
361+
setDefaultConstrainedExcept(fp::ebIgnore);
360362
}
361-
IsFPConstrained = IsCon;
363+
setIsFPConstrained(IsCon);
362364
}
363365

364366
/// Query for the use of constrained floating point math

llvm/lib/CodeGen/AtomicExpandPass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ struct ReplacementIRBuilder
159159
SetInsertPoint(I);
160160
this->CollectMetadataToCopy(I, {LLVMContext::MD_pcsections});
161161
if (BB->getParent()->getAttributes().hasFnAttr(Attribute::StrictFP))
162-
this->setIsFPConstrained(true);
162+
this->resetModeToStrictFP(true);
163163

164164
MMRAMD = I->getMetadata(LLVMContext::MD_mmra);
165165
}
@@ -1706,7 +1706,7 @@ bool AtomicExpandImpl::tryExpandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
17061706
bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
17071707
CreateCmpXchgInstFun CreateCmpXchg) {
17081708
ReplacementIRBuilder Builder(AI, AI->getDataLayout());
1709-
Builder.setIsFPConstrained(
1709+
Builder.resetModeToStrictFP(
17101710
AI->getFunction()->hasFnAttribute(Attribute::StrictFP));
17111711

17121712
// FIXME: If FP exceptions are observable, we should force them off for the

llvm/lib/CodeGen/HardwareLoops.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ Value *HardwareLoop::InitLoopCount() {
503503
Value* HardwareLoop::InsertIterationSetup(Value *LoopCountInit) {
504504
IRBuilder<> Builder(BeginBB->getTerminator());
505505
if (BeginBB->getParent()->getAttributes().hasFnAttr(Attribute::StrictFP))
506-
Builder.setIsFPConstrained(true);
506+
Builder.resetModeToStrictFP(true);
507507
Type *Ty = LoopCountInit->getType();
508508
bool UsePhi = UsePHICounter || Opts.ForcePhi;
509509
Intrinsic::ID ID = UseLoopGuard
@@ -537,7 +537,7 @@ void HardwareLoop::InsertLoopDec() {
537537
IRBuilder<> CondBuilder(ExitBranch);
538538
if (ExitBranch->getParent()->getParent()->getAttributes().hasFnAttr(
539539
Attribute::StrictFP))
540-
CondBuilder.setIsFPConstrained(true);
540+
CondBuilder.resetModeToStrictFP(true);
541541

542542
Value *Ops[] = { LoopDecrement };
543543
Value *NewCond = CondBuilder.CreateIntrinsic(Intrinsic::loop_decrement,
@@ -560,7 +560,7 @@ Instruction* HardwareLoop::InsertLoopRegDec(Value *EltsRem) {
560560
IRBuilder<> CondBuilder(ExitBranch);
561561
if (ExitBranch->getParent()->getParent()->getAttributes().hasFnAttr(
562562
Attribute::StrictFP))
563-
CondBuilder.setIsFPConstrained(true);
563+
CondBuilder.resetModeToStrictFP(true);
564564

565565
Value *Ops[] = { EltsRem, LoopDecrement };
566566
Value *Call = CondBuilder.CreateIntrinsic(Intrinsic::loop_decrement_reg,

llvm/lib/IR/AsmWriter.cpp

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ static cl::opt<bool> PrintProfData(
100100
"print-prof-data", cl::Hidden,
101101
cl::desc("Pretty print perf data (branch weights, etc) when dumping"));
102102

103+
static cl::opt<bool> PrintFPMemoryEffects(
104+
"print-fp-memory-effects", cl::Hidden,
105+
cl::desc("Pretty print floating-point memory effects when dumping"));
106+
103107
// Make virtual table appear in this compilation unit.
104108
AssemblyAnnotationWriter::~AssemblyAnnotationWriter() = default;
105109

@@ -4359,6 +4363,25 @@ void AssemblyWriter::printGCRelocateComment(const GCRelocateInst &Relocate) {
43594363
Out << ")";
43604364
}
43614365

4366+
static void printFPMemoryEffects(raw_ostream &Out, MemoryEffects ME) {
4367+
ModRefInfo MR = ME.getModRef(IRMemLocation::InaccessibleMem);
4368+
Out << " ; fpe=[";
4369+
switch (MR) {
4370+
case ModRefInfo::NoModRef:
4371+
break;
4372+
case ModRefInfo::Ref:
4373+
Out << "r";
4374+
break;
4375+
case ModRefInfo::Mod:
4376+
Out << "w";
4377+
break;
4378+
case ModRefInfo::ModRef:
4379+
Out << "rw";
4380+
break;
4381+
}
4382+
Out << "]";
4383+
}
4384+
43624385
/// printInfoComment - Print a little comment after the instruction indicating
43634386
/// which slot it occupies.
43644387
void AssemblyWriter::printInfoComment(const Value &V) {
@@ -4389,30 +4412,14 @@ void AssemblyWriter::printInfoComment(const Value &V) {
43894412
if (PrintInstAddrs)
43904413
Out << " ; " << &V;
43914414

4392-
if (auto *CI = dyn_cast<CallInst>(&V))
4393-
if (Intrinsic::ID IID = CI->getIntrinsicID())
4394-
if (IntrinsicInst::isFloatingPointOperation(IID))
4395-
if (const BasicBlock *BB = CI->getParent())
4396-
if (const Function *F = BB->getParent())
4397-
if (F->hasFnAttribute(Attribute::StrictFP)) {
4398-
MemoryEffects ME = CI->getMemoryEffects();
4399-
ModRefInfo MR = ME.getModRef(IRMemLocation::InaccessibleMem);
4400-
Out << " ; fpe=[";
4401-
switch (MR) {
4402-
case ModRefInfo::NoModRef:
4403-
break;
4404-
case ModRefInfo::Ref:
4405-
Out << "r";
4406-
break;
4407-
case ModRefInfo::Mod:
4408-
Out << "w";
4409-
break;
4410-
case ModRefInfo::ModRef:
4411-
Out << "rw";
4412-
break;
4413-
}
4414-
Out << "]";
4415-
}
4415+
if (PrintFPMemoryEffects) {
4416+
if (auto *CI = dyn_cast<CallInst>(&V))
4417+
if (Intrinsic::ID IID = CI->getIntrinsicID())
4418+
if (const Function *F = CI->getFunction())
4419+
if (IntrinsicInst::isFloatingPointOperation(IID) &&
4420+
F->hasFnAttribute(Attribute::StrictFP))
4421+
printFPMemoryEffects(Out, CI->getMemoryEffects());
4422+
}
44164423
}
44174424

44184425
static void maybePrintCallAddrSpace(const Value *Operand, const Instruction *I,

llvm/lib/IR/FPEnv.cpp

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,20 @@ std::optional<StringRef> convertRoundingModeToBundle(RoundingMode UseRounding) {
7676
std::optional<StringRef> RoundingStr;
7777
switch (UseRounding) {
7878
case RoundingMode::Dynamic:
79-
RoundingStr = "dynamic";
80-
break;
79+
return "dynamic";
8180
case RoundingMode::NearestTiesToEven:
82-
RoundingStr = "tonearest";
83-
break;
81+
return "tonearest";
8482
case RoundingMode::NearestTiesToAway:
85-
RoundingStr = "tonearestaway";
86-
break;
83+
return "tonearestaway";
8784
case RoundingMode::TowardNegative:
88-
RoundingStr = "downward";
89-
break;
85+
return "downward";
9086
case RoundingMode::TowardPositive:
91-
RoundingStr = "upward";
92-
break;
87+
return "upward";
9388
case RoundingMode::TowardZero:
94-
RoundingStr = "towardzero";
95-
break;
89+
return "towardzero";
9690
default:
97-
break;
91+
return std::nullopt;
9892
}
99-
return RoundingStr;
10093
}
10194

10295
std::optional<fp::ExceptionBehavior>
@@ -139,16 +132,14 @@ convertExceptionBehaviorToBundle(fp::ExceptionBehavior UseExcept) {
139132
std::optional<StringRef> ExceptStr;
140133
switch (UseExcept) {
141134
case fp::ebStrict:
142-
ExceptStr = "strict";
143-
break;
135+
return "strict";
144136
case fp::ebIgnore:
145-
ExceptStr = "ignore";
146-
break;
137+
return "ignore";
147138
case fp::ebMayTrap:
148-
ExceptStr = "maytrap";
149-
break;
139+
return "maytrap";
140+
default:
141+
return std::nullopt;
150142
}
151-
return ExceptStr;
152143
}
153144

154145
Intrinsic::ID getConstrainedIntrinsicID(const Instruction &Instr) {

llvm/lib/IR/IRBuilder.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ CallInst *IRBuilderBase::CreateCall(FunctionType *FTy, Value *Callee,
125125
if (const auto *Func = dyn_cast<Function>(Callee))
126126
if (Intrinsic::ID ID = Func->getIntrinsicID())
127127
if (IntrinsicInst::isFloatingPointOperation(ID)) {
128-
// If the builder has non-default floating-point options, add
128+
// If the builder specifies non-default floating-point options, add
129129
// corresponding operand bundle unless a bundle with such tag is already
130130
// present.
131131
bool NeedRounding;
@@ -140,23 +140,24 @@ CallInst *IRBuilderBase::CreateCall(FunctionType *FTy, Value *Callee,
140140
assert(DefaultConstrainedExcept == fp::ebIgnore &&
141141
"FP exception in default mode must be ignored");
142142
}
143+
// Options specified by bundles have higher precedence.
144+
for (const auto &Bundle : OpBundles) {
145+
if (NeedRounding && Bundle.getTag() == "fp.round")
146+
NeedRounding = false;
147+
if (NeedExceptions && Bundle.getTag() == "fp.except")
148+
NeedExceptions = false;
149+
}
143150
if (NeedRounding || NeedExceptions) {
144-
for (const auto &Bundle : OpBundles) {
145-
if (NeedRounding && Bundle.getTag() == "fp.round")
146-
NeedRounding = false;
147-
if (NeedExceptions && Bundle.getTag() == "fp.except")
148-
NeedExceptions = false;
149-
}
150-
if (NeedRounding || NeedExceptions) {
151-
ActualBundles.append(OpBundles.begin(), OpBundles.end());
152-
if (NeedRounding)
153-
createRoundingBundle(ActualBundles, DefaultConstrainedRounding);
154-
if (NeedExceptions)
155-
createExceptionBundle(ActualBundles, DefaultConstrainedExcept);
156-
ActualBundlesRef = ActualBundles;
157-
}
151+
ActualBundles.append(OpBundles.begin(), OpBundles.end());
152+
if (NeedRounding)
153+
createRoundingBundle(ActualBundles, DefaultConstrainedRounding);
154+
if (NeedExceptions)
155+
createExceptionBundle(ActualBundles, DefaultConstrainedExcept);
156+
ActualBundlesRef = ActualBundles;
158157
}
159158
if (IsFPConstrained) {
159+
// Due to potential reading FP exception bits, in strictfp mode the
160+
// memory effects must include read/write access to FPE.
160161
MemoryEffects FME = Func->getMemoryEffects();
161162
NeedUpdateMemoryEffects = !FME.doesAccessInaccessibleMem();
162163
}

llvm/lib/Target/AMDGPU/AMDGPUAtomicOptimizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ void AMDGPUAtomicOptimizerImpl::optimizeAtomic(Instruction &I,
649649
IRBuilder<> B(&I);
650650

651651
if (AtomicRMWInst::isFPOperation(Op)) {
652-
B.setIsFPConstrained(I.getFunction()->hasFnAttribute(Attribute::StrictFP));
652+
B.resetModeToStrictFP(I.getFunction()->hasFnAttribute(Attribute::StrictFP));
653653
}
654654

655655
// If we are in a pixel shader, because of how we have to mask out helper

0 commit comments

Comments
 (0)