Skip to content

Commit 549f55f

Browse files
committed
[Clang][CodeGen] Do not promote if complex divisor is real
Relates-to: #131129
1 parent a4741c0 commit 549f55f

File tree

2 files changed

+36
-52
lines changed

2 files changed

+36
-52
lines changed

clang/lib/CodeGen/CGExprComplex.cpp

+20-16
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,7 @@ class ComplexExprEmitter
286286
ComplexPairTy EmitComplexBinOpLibCall(StringRef LibCallName,
287287
const BinOpInfo &Op);
288288

289-
QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType,
290-
bool IsDivOpCode) {
289+
QualType HigherPrecisionTypeForComplexArithmetic(QualType ElementType) {
291290
ASTContext &Ctx = CGF.getContext();
292291
const QualType HigherElementType =
293292
Ctx.GetHigherPrecisionFPType(ElementType);
@@ -314,7 +313,7 @@ class ComplexExprEmitter
314313
}
315314

316315
QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
317-
bool IsDivOpCode = false) {
316+
bool IsComplexDivisor) {
318317
if (auto *CT = Ty->getAs<ComplexType>()) {
319318
QualType ElementType = CT->getElementType();
320319
bool IsFloatingType = ElementType->isFloatingType();
@@ -325,10 +324,9 @@ class ComplexExprEmitter
325324
Features.getComplexRangeOverride() ==
326325
CGF.getLangOpts().getComplexRange();
327326

328-
if (IsDivOpCode && IsFloatingType && IsComplexRangePromoted &&
327+
if (IsComplexDivisor && IsFloatingType && IsComplexRangePromoted &&
329328
(HasNoComplexRangeOverride || HasMatchingComplexRange))
330-
return HigherPrecisionTypeForComplexArithmetic(ElementType,
331-
IsDivOpCode);
329+
return HigherPrecisionTypeForComplexArithmetic(ElementType);
332330
if (ElementType.UseExcessPrecision(CGF.getContext()))
333331
return CGF.getContext().getComplexType(CGF.getContext().FloatTy);
334332
}
@@ -339,9 +337,10 @@ class ComplexExprEmitter
339337

340338
#define HANDLEBINOP(OP) \
341339
ComplexPairTy VisitBin##OP(const BinaryOperator *E) { \
342-
QualType promotionTy = getPromotionType( \
343-
E->getStoredFPFeaturesOrDefault(), E->getType(), \
344-
(E->getOpcode() == BinaryOperatorKind::BO_Div) ? true : false); \
340+
QualType promotionTy = \
341+
getPromotionType(E->getStoredFPFeaturesOrDefault(), E->getType(), \
342+
(E->getOpcode() == BinaryOperatorKind::BO_Div && \
343+
E->getRHS()->getType()->isAnyComplexType())); \
345344
ComplexPairTy result = EmitBin##OP(EmitBinOps(E, promotionTy)); \
346345
if (!promotionTy.isNull()) \
347346
result = CGF.EmitUnPromotedValue(result, E->getType()); \
@@ -639,7 +638,8 @@ ComplexPairTy ComplexExprEmitter::VisitUnaryPlus(const UnaryOperator *E,
639638
QualType promotionTy =
640639
PromotionType.isNull()
641640
? getPromotionType(E->getStoredFPFeaturesOrDefault(),
642-
E->getSubExpr()->getType())
641+
E->getSubExpr()->getType(),
642+
/*IsComplexDivisor=*/false)
643643
: PromotionType;
644644
ComplexPairTy result = VisitPlus(E, promotionTy);
645645
if (!promotionTy.isNull())
@@ -661,7 +661,8 @@ ComplexPairTy ComplexExprEmitter::VisitUnaryMinus(const UnaryOperator *E,
661661
QualType promotionTy =
662662
PromotionType.isNull()
663663
? getPromotionType(E->getStoredFPFeaturesOrDefault(),
664-
E->getSubExpr()->getType())
664+
E->getSubExpr()->getType(),
665+
/*IsComplexDivisor=*/false)
665666
: PromotionType;
666667
ComplexPairTy result = VisitMinus(E, promotionTy);
667668
if (!promotionTy.isNull())
@@ -1218,14 +1219,16 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
12181219
// improve codegen a little.
12191220
QualType PromotionTypeCR;
12201221
PromotionTypeCR = getPromotionType(E->getStoredFPFeaturesOrDefault(),
1221-
E->getComputationResultType());
1222+
E->getComputationResultType(),
1223+
/*IsComplexDivisor=*/false);
12221224
if (PromotionTypeCR.isNull())
12231225
PromotionTypeCR = E->getComputationResultType();
12241226
OpInfo.Ty = PromotionTypeCR;
12251227
QualType ComplexElementTy =
12261228
OpInfo.Ty->castAs<ComplexType>()->getElementType();
1227-
QualType PromotionTypeRHS = getPromotionType(
1228-
E->getStoredFPFeaturesOrDefault(), E->getRHS()->getType());
1229+
QualType PromotionTypeRHS =
1230+
getPromotionType(E->getStoredFPFeaturesOrDefault(),
1231+
E->getRHS()->getType(), /*IsComplexDivisor=*/false);
12291232

12301233
// The RHS should have been converted to the computation type.
12311234
if (E->getRHS()->getType()->isRealFloatingType()) {
@@ -1253,8 +1256,9 @@ EmitCompoundAssignLValue(const CompoundAssignOperator *E,
12531256

12541257
// Load from the l-value and convert it.
12551258
SourceLocation Loc = E->getExprLoc();
1256-
QualType PromotionTypeLHS = getPromotionType(
1257-
E->getStoredFPFeaturesOrDefault(), E->getComputationLHSType());
1259+
QualType PromotionTypeLHS =
1260+
getPromotionType(E->getStoredFPFeaturesOrDefault(),
1261+
E->getComputationLHSType(), /*IsComplexDivisor=*/false);
12581262
if (LHSTy->isAnyComplexType()) {
12591263
ComplexPairTy LHSVal = EmitLoadOfLValue(LHS, Loc);
12601264
if (!PromotionTypeLHS.isNull())

clang/test/CodeGen/cx-complex-range-real.c

+16-36
Original file line numberDiff line numberDiff line change
@@ -340,18 +340,13 @@ _Complex float mulbf(float a, _Complex float b) {
340340
// PRMTD-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
341341
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
342342
// PRMTD-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
343-
// PRMTD-NEXT: [[EXT:%.*]] = fpext float [[A_REAL]] to double
344-
// PRMTD-NEXT: [[EXT1:%.*]] = fpext float [[A_IMAG]] to double
345343
// PRMTD-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
346-
// PRMTD-NEXT: [[EXT2:%.*]] = fpext float [[TMP0]] to double
347-
// PRMTD-NEXT: [[TMP1:%.*]] = fdiv double [[EXT]], [[EXT2]]
348-
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv double [[EXT1]], [[EXT2]]
349-
// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc double [[TMP1]] to float
350-
// PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc double [[TMP2]] to float
344+
// PRMTD-NEXT: [[TMP1:%.*]] = fdiv float [[A_REAL]], [[TMP0]]
345+
// PRMTD-NEXT: [[TMP2:%.*]] = fdiv float [[A_IMAG]], [[TMP0]]
351346
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
352347
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
353-
// PRMTD-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
354-
// PRMTD-NEXT: store float [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 4
348+
// PRMTD-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
349+
// PRMTD-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
355350
// PRMTD-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
356351
// PRMTD-NEXT: ret <2 x float> [[TMP3]]
357352
//
@@ -367,18 +362,13 @@ _Complex float mulbf(float a, _Complex float b) {
367362
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load float, ptr [[A_REALP]], align 4
368363
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[A]], i32 0, i32 1
369364
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load float, ptr [[A_IMAGP]], align 4
370-
// PRMTD_STRICT-NEXT: [[EXT:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
371-
// PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
372365
// PRMTD_STRICT-NEXT: [[TMP0:%.*]] = load float, ptr [[B_ADDR]], align 4
373-
// PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call double @llvm.experimental.constrained.fpext.f64.f32(float [[TMP0]], metadata !"fpexcept.strict") #[[ATTR3]]
374-
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
375-
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[EXT1]], double [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
376-
// PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP1]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
377-
// PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call float @llvm.experimental.constrained.fptrunc.f32.f64(double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
366+
// PRMTD_STRICT-NEXT: [[TMP1:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_REAL]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
367+
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = call float @llvm.experimental.constrained.fdiv.f32(float [[A_IMAG]], float [[TMP0]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
378368
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 0
379369
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { float, float }, ptr [[RETVAL]], i32 0, i32 1
380-
// PRMTD_STRICT-NEXT: store float [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 4
381-
// PRMTD_STRICT-NEXT: store float [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 4
370+
// PRMTD_STRICT-NEXT: store float [[TMP1]], ptr [[RETVAL_REALP]], align 4
371+
// PRMTD_STRICT-NEXT: store float [[TMP2]], ptr [[RETVAL_IMAGP]], align 4
382372
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = load <2 x float>, ptr [[RETVAL]], align 4
383373
// PRMTD_STRICT-NEXT: ret <2 x float> [[TMP3]]
384374
//
@@ -539,18 +529,13 @@ void divassignf(_Complex float *a, float b) {
539529
// PRMTD-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
540530
// PRMTD-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
541531
// PRMTD-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
542-
// PRMTD-NEXT: [[EXT:%.*]] = fpext double [[A_REAL]] to x86_fp80
543-
// PRMTD-NEXT: [[EXT1:%.*]] = fpext double [[A_IMAG]] to x86_fp80
544532
// PRMTD-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
545-
// PRMTD-NEXT: [[EXT2:%.*]] = fpext double [[TMP2]] to x86_fp80
546-
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv x86_fp80 [[EXT]], [[EXT2]]
547-
// PRMTD-NEXT: [[TMP4:%.*]] = fdiv x86_fp80 [[EXT1]], [[EXT2]]
548-
// PRMTD-NEXT: [[UNPROMOTION:%.*]] = fptrunc x86_fp80 [[TMP3]] to double
549-
// PRMTD-NEXT: [[UNPROMOTION3:%.*]] = fptrunc x86_fp80 [[TMP4]] to double
533+
// PRMTD-NEXT: [[TMP3:%.*]] = fdiv double [[A_REAL]], [[TMP2]]
534+
// PRMTD-NEXT: [[TMP4:%.*]] = fdiv double [[A_IMAG]], [[TMP2]]
550535
// PRMTD-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
551536
// PRMTD-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
552-
// PRMTD-NEXT: store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
553-
// PRMTD-NEXT: store double [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 8
537+
// PRMTD-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
538+
// PRMTD-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
554539
// PRMTD-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
555540
// PRMTD-NEXT: ret { double, double } [[TMP5]]
556541
//
@@ -569,18 +554,13 @@ void divassignf(_Complex float *a, float b) {
569554
// PRMTD_STRICT-NEXT: [[A_REAL:%.*]] = load double, ptr [[A_REALP]], align 8
570555
// PRMTD_STRICT-NEXT: [[A_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[A]], i32 0, i32 1
571556
// PRMTD_STRICT-NEXT: [[A_IMAG:%.*]] = load double, ptr [[A_IMAGP]], align 8
572-
// PRMTD_STRICT-NEXT: [[EXT:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_REAL]], metadata !"fpexcept.strict") #[[ATTR3]]
573-
// PRMTD_STRICT-NEXT: [[EXT1:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[A_IMAG]], metadata !"fpexcept.strict") #[[ATTR3]]
574557
// PRMTD_STRICT-NEXT: [[TMP2:%.*]] = load double, ptr [[B_ADDR]], align 8
575-
// PRMTD_STRICT-NEXT: [[EXT2:%.*]] = call x86_fp80 @llvm.experimental.constrained.fpext.f80.f64(double [[TMP2]], metadata !"fpexcept.strict") #[[ATTR3]]
576-
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
577-
// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call x86_fp80 @llvm.experimental.constrained.fdiv.f80(x86_fp80 [[EXT1]], x86_fp80 [[EXT2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
578-
// PRMTD_STRICT-NEXT: [[UNPROMOTION:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP3]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
579-
// PRMTD_STRICT-NEXT: [[UNPROMOTION3:%.*]] = call double @llvm.experimental.constrained.fptrunc.f64.f80(x86_fp80 [[TMP4]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
558+
// PRMTD_STRICT-NEXT: [[TMP3:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_REAL]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
559+
// PRMTD_STRICT-NEXT: [[TMP4:%.*]] = call double @llvm.experimental.constrained.fdiv.f64(double [[A_IMAG]], double [[TMP2]], metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]]
580560
// PRMTD_STRICT-NEXT: [[RETVAL_REALP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 0
581561
// PRMTD_STRICT-NEXT: [[RETVAL_IMAGP:%.*]] = getelementptr inbounds nuw { double, double }, ptr [[RETVAL]], i32 0, i32 1
582-
// PRMTD_STRICT-NEXT: store double [[UNPROMOTION]], ptr [[RETVAL_REALP]], align 8
583-
// PRMTD_STRICT-NEXT: store double [[UNPROMOTION3]], ptr [[RETVAL_IMAGP]], align 8
562+
// PRMTD_STRICT-NEXT: store double [[TMP3]], ptr [[RETVAL_REALP]], align 8
563+
// PRMTD_STRICT-NEXT: store double [[TMP4]], ptr [[RETVAL_IMAGP]], align 8
584564
// PRMTD_STRICT-NEXT: [[TMP5:%.*]] = load { double, double }, ptr [[RETVAL]], align 8
585565
// PRMTD_STRICT-NEXT: ret { double, double } [[TMP5]]
586566
//

0 commit comments

Comments
 (0)