[clang] [clang] Add support for -fcx-limited-range and #pragma CX_LIMITED_RANGE. (PR #68820)
Joshua Cranmer via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 25 12:55:10 PDT 2023
================
@@ -846,6 +865,105 @@ ComplexPairTy ComplexExprEmitter::EmitBinMul(const BinOpInfo &Op) {
return ComplexPairTy(ResR, ResI);
}
+ComplexPairTy ComplexExprEmitter::EmitAlgebraicDiv(llvm::Value *LHSr,
+ llvm::Value *LHSi,
+ llvm::Value *RHSr,
+ llvm::Value *RHSi) {
+ // (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd))
+ llvm::Value *DSTr, *DSTi;
+
+ llvm::Value *AC = Builder.CreateFMul(LHSr, RHSr); // a*c
+ llvm::Value *BD = Builder.CreateFMul(LHSi, RHSi); // b*d
+ llvm::Value *ACpBD = Builder.CreateFAdd(AC, BD); // ac+bd
+
+ llvm::Value *CC = Builder.CreateFMul(RHSr, RHSr); // c*c
+ llvm::Value *DD = Builder.CreateFMul(RHSi, RHSi); // d*d
+ llvm::Value *CCpDD = Builder.CreateFAdd(CC, DD); // cc+dd
+
+ llvm::Value *BC = Builder.CreateFMul(LHSi, RHSr); // b*c
+ llvm::Value *AD = Builder.CreateFMul(LHSr, RHSi); // a*d
+ llvm::Value *BCmAD = Builder.CreateFSub(BC, AD); // bc-ad
+
+ DSTr = Builder.CreateFDiv(ACpBD, CCpDD);
+ DSTi = Builder.CreateFDiv(BCmAD, CCpDD);
+ return ComplexPairTy(DSTr, DSTi);
+}
+
+/// EmitFAbs - Emit a call to @llvm.fabs.
+static llvm::Value *EmitllvmFAbs(CodeGenFunction &CGF, llvm::Value *Value) {
+ llvm::Function *Func =
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::fabs, Value->getType());
+ llvm::Value *Call = CGF.Builder.CreateCall(Func, Value);
+ return Call;
+}
+
+ComplexPairTy ComplexExprEmitter::EmitRangeReductionDiv(llvm::Value *LHSr,
+ llvm::Value *LHSi,
+ llvm::Value *RHSr,
+ llvm::Value *RHSi) {
+ // (a + ib) / (c + id) = (e + if)
+ llvm::Value *FAbsRHSr = EmitllvmFAbs(CGF, RHSr); // |c|
+ llvm::Value *FAbsRHSi = EmitllvmFAbs(CGF, RHSi); // |d|
+ // |c| >= |d|
+ llvm::Value *IsR = Builder.CreateFCmpUGT(FAbsRHSr, FAbsRHSi, "abs_cmp");
+
+ llvm::BasicBlock *TrueBB = CGF.createBasicBlock("true_bb_name");
+ llvm::BasicBlock *FalseBB = CGF.createBasicBlock("false_bb_name");
+ llvm::BasicBlock *ContBB = CGF.createBasicBlock("cont_bb");
+ Builder.CreateCondBr(IsR, TrueBB, FalseBB);
+
+ CGF.EmitBlock(TrueBB);
+ // abs(c) >= abs(d)
+ // r = d/c
+ // tmp = c + rd
+ // e = (a + br)/tmp
+ // f = (b - ar)/tmp
+ llvm::Value *DdC = Builder.CreateFDiv(RHSi, RHSr); // d/c
+
+ llvm::Value *RD = Builder.CreateFMul(DdC, RHSi); // (d/c)d
+ llvm::Value *CpRD = Builder.CreateFAdd(RHSr, RD); // c+((d/c)d)
+
+ llvm::Value *T3 = Builder.CreateFMul(LHSi, DdC); // b(d/c)
+ llvm::Value *T4 = Builder.CreateFAdd(LHSr, T3); // a+b(d/c)
+ llvm::Value *DSTTr = Builder.CreateFDiv(T4, CpRD); // (a+b(d/c))/(c+(d/c)d)
+
+ llvm::Value *T5 = Builder.CreateFMul(LHSr, DdC); // ar
+ llvm::Value *T6 = Builder.CreateFSub(LHSi, T5); // b-ar
+ llvm::Value *DSTTi = Builder.CreateFDiv(T6, CpRD); // (b-a(d/c))/(c+(d/c)d)
+ Builder.CreateBr(ContBB);
+
+ CGF.EmitBlock(FalseBB);
+ // abs(c) < abs(d)
+ // r = c/d
+ // tmp = d + rc
+ // e = (ar + b)/tmp
+ // f = (br - a)/tmp
+ llvm::Value *CdD = Builder.CreateFDiv(RHSr, RHSi); // c/d
+
+ llvm::Value *RC = Builder.CreateFMul(CdD, RHSr); // (c/d)c
+ llvm::Value *DpRC = Builder.CreateFAdd(RHSi, RC); // d+(c/d)c
+
+ llvm::Value *T7 = Builder.CreateFAdd(CdD, RHSi); // (c/d)+b
+ llvm::Value *T8 = Builder.CreateFMul(LHSr, T7); // a((c/d)+b)
----------------
jcranmer-intel wrote:
This code is wrong, I think, it should be mul then add.
https://github.com/llvm/llvm-project/pull/68820
More information about the cfe-commits
mailing list