@@ -1629,6 +1629,18 @@ static bool isManifestConstant(const Constant *c) {
1629
1629
return false ;
1630
1630
}
1631
1631
1632
+ static bool getConstIntOrUndef (Value *Op, const APInt *&C) {
1633
+ if (auto *CI = dyn_cast<ConstantInt>(Op)) {
1634
+ C = &CI->getValue ();
1635
+ return true ;
1636
+ }
1637
+ if (isa<UndefValue>(Op)) {
1638
+ C = nullptr ;
1639
+ return true ;
1640
+ }
1641
+ return false ;
1642
+ }
1643
+
1632
1644
Constant *ConstantFoldScalarCall (StringRef Name, unsigned IntrinsicID, Type *Ty,
1633
1645
ArrayRef<Constant *> Operands,
1634
1646
const TargetLibraryInfo *TLI,
@@ -1643,8 +1655,10 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
1643
1655
return nullptr ;
1644
1656
}
1645
1657
if (isa<UndefValue>(Operands[0 ])) {
1646
- // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN
1647
- if (IntrinsicID == Intrinsic::cos)
1658
+ // cosine(arg) is between -1 and 1. cosine(invalid arg) is NaN.
1659
+ // ctpop() is between 0 and bitwidth, pick 0 for undef.
1660
+ if (IntrinsicID == Intrinsic::cos ||
1661
+ IntrinsicID == Intrinsic::ctpop)
1648
1662
return Constant::getNullValue (Ty);
1649
1663
if (IntrinsicID == Intrinsic::bswap ||
1650
1664
IntrinsicID == Intrinsic::bitreverse ||
@@ -1995,62 +2009,92 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
1995
2009
return nullptr ;
1996
2010
}
1997
2011
1998
- if (auto *Op1 = dyn_cast<ConstantInt>(Operands[0 ])) {
1999
- if (auto *Op2 = dyn_cast<ConstantInt>(Operands[1 ])) {
2012
+ if (Operands[0 ]->getType ()->isIntegerTy () &&
2013
+ Operands[1 ]->getType ()->isIntegerTy ()) {
2014
+ const APInt *C0, *C1;
2015
+ if (!getConstIntOrUndef (Operands[0 ], C0) ||
2016
+ !getConstIntOrUndef (Operands[1 ], C1))
2017
+ return nullptr ;
2018
+
2019
+ switch (IntrinsicID) {
2020
+ default : break ;
2021
+ case Intrinsic::smul_with_overflow:
2022
+ case Intrinsic::umul_with_overflow:
2023
+ // Even if both operands are undef, we cannot fold muls to undef
2024
+ // in the general case. For example, on i2 there are no inputs
2025
+ // that would produce { i2 -1, i1 true } as the result.
2026
+ if (!C0 || !C1)
2027
+ return Constant::getNullValue (Ty);
2028
+ LLVM_FALLTHROUGH;
2029
+ case Intrinsic::sadd_with_overflow:
2030
+ case Intrinsic::uadd_with_overflow:
2031
+ case Intrinsic::ssub_with_overflow:
2032
+ case Intrinsic::usub_with_overflow: {
2033
+ if (!C0 || !C1)
2034
+ return UndefValue::get (Ty);
2035
+
2036
+ APInt Res;
2037
+ bool Overflow;
2000
2038
switch (IntrinsicID) {
2001
- default : break ;
2039
+ default : llvm_unreachable ( " Invalid case " ) ;
2002
2040
case Intrinsic::sadd_with_overflow:
2041
+ Res = C0->sadd_ov (*C1, Overflow);
2042
+ break ;
2003
2043
case Intrinsic::uadd_with_overflow:
2044
+ Res = C0->uadd_ov (*C1, Overflow);
2045
+ break ;
2004
2046
case Intrinsic::ssub_with_overflow:
2047
+ Res = C0->ssub_ov (*C1, Overflow);
2048
+ break ;
2005
2049
case Intrinsic::usub_with_overflow:
2050
+ Res = C0->usub_ov (*C1, Overflow);
2051
+ break ;
2006
2052
case Intrinsic::smul_with_overflow:
2007
- case Intrinsic::umul_with_overflow: {
2008
- APInt Res;
2009
- bool Overflow;
2010
- switch (IntrinsicID) {
2011
- default : llvm_unreachable (" Invalid case" );
2012
- case Intrinsic::sadd_with_overflow:
2013
- Res = Op1->getValue ().sadd_ov (Op2->getValue (), Overflow);
2014
- break ;
2015
- case Intrinsic::uadd_with_overflow:
2016
- Res = Op1->getValue ().uadd_ov (Op2->getValue (), Overflow);
2017
- break ;
2018
- case Intrinsic::ssub_with_overflow:
2019
- Res = Op1->getValue ().ssub_ov (Op2->getValue (), Overflow);
2020
- break ;
2021
- case Intrinsic::usub_with_overflow:
2022
- Res = Op1->getValue ().usub_ov (Op2->getValue (), Overflow);
2023
- break ;
2024
- case Intrinsic::smul_with_overflow:
2025
- Res = Op1->getValue ().smul_ov (Op2->getValue (), Overflow);
2026
- break ;
2027
- case Intrinsic::umul_with_overflow:
2028
- Res = Op1->getValue ().umul_ov (Op2->getValue (), Overflow);
2029
- break ;
2030
- }
2031
- Constant *Ops[] = {
2032
- ConstantInt::get (Ty->getContext (), Res),
2033
- ConstantInt::get (Type::getInt1Ty (Ty->getContext ()), Overflow)
2034
- };
2035
- return ConstantStruct::get (cast<StructType>(Ty), Ops);
2036
- }
2037
- case Intrinsic::uadd_sat:
2038
- return ConstantInt::get (Ty, Op1->getValue ().uadd_sat (Op2->getValue ()));
2039
- case Intrinsic::sadd_sat:
2040
- return ConstantInt::get (Ty, Op1->getValue ().sadd_sat (Op2->getValue ()));
2041
- case Intrinsic::usub_sat:
2042
- return ConstantInt::get (Ty, Op1->getValue ().usub_sat (Op2->getValue ()));
2043
- case Intrinsic::ssub_sat:
2044
- return ConstantInt::get (Ty, Op1->getValue ().ssub_sat (Op2->getValue ()));
2045
- case Intrinsic::cttz:
2046
- if (Op2->isOne () && Op1->isZero ()) // cttz(0, 1) is undef.
2047
- return UndefValue::get (Ty);
2048
- return ConstantInt::get (Ty, Op1->getValue ().countTrailingZeros ());
2049
- case Intrinsic::ctlz:
2050
- if (Op2->isOne () && Op1->isZero ()) // ctlz(0, 1) is undef.
2051
- return UndefValue::get (Ty);
2052
- return ConstantInt::get (Ty, Op1->getValue ().countLeadingZeros ());
2053
+ Res = C0->smul_ov (*C1, Overflow);
2054
+ break ;
2055
+ case Intrinsic::umul_with_overflow:
2056
+ Res = C0->umul_ov (*C1, Overflow);
2057
+ break ;
2053
2058
}
2059
+ Constant *Ops[] = {
2060
+ ConstantInt::get (Ty->getContext (), Res),
2061
+ ConstantInt::get (Type::getInt1Ty (Ty->getContext ()), Overflow)
2062
+ };
2063
+ return ConstantStruct::get (cast<StructType>(Ty), Ops);
2064
+ }
2065
+ case Intrinsic::uadd_sat:
2066
+ case Intrinsic::sadd_sat:
2067
+ if (!C0 && !C1)
2068
+ return UndefValue::get (Ty);
2069
+ if (!C0 || !C1)
2070
+ return Constant::getAllOnesValue (Ty);
2071
+ if (IntrinsicID == Intrinsic::uadd_sat)
2072
+ return ConstantInt::get (Ty, C0->uadd_sat (*C1));
2073
+ else
2074
+ return ConstantInt::get (Ty, C0->sadd_sat (*C1));
2075
+ case Intrinsic::usub_sat:
2076
+ case Intrinsic::ssub_sat:
2077
+ if (!C0 && !C1)
2078
+ return UndefValue::get (Ty);
2079
+ if (!C0 || !C1)
2080
+ return Constant::getNullValue (Ty);
2081
+ if (IntrinsicID == Intrinsic::usub_sat)
2082
+ return ConstantInt::get (Ty, C0->usub_sat (*C1));
2083
+ else
2084
+ return ConstantInt::get (Ty, C0->ssub_sat (*C1));
2085
+ case Intrinsic::cttz:
2086
+ case Intrinsic::ctlz:
2087
+ assert (C1 && " Must be constant int" );
2088
+
2089
+ // cttz(0, 1) and ctlz(0, 1) are undef.
2090
+ if (C1->isOneValue () && (!C0 || C0->isNullValue ()))
2091
+ return UndefValue::get (Ty);
2092
+ if (!C0)
2093
+ return Constant::getNullValue (Ty);
2094
+ if (IntrinsicID == Intrinsic::cttz)
2095
+ return ConstantInt::get (Ty, C0->countTrailingZeros ());
2096
+ else
2097
+ return ConstantInt::get (Ty, C0->countLeadingZeros ());
2054
2098
}
2055
2099
2056
2100
return nullptr ;
@@ -2136,26 +2180,33 @@ Constant *ConstantFoldScalarCall(StringRef Name, unsigned IntrinsicID, Type *Ty,
2136
2180
}
2137
2181
2138
2182
if (IntrinsicID == Intrinsic::fshl || IntrinsicID == Intrinsic::fshr) {
2139
- auto *C0 = dyn_cast<ConstantInt>(Operands[ 0 ]) ;
2140
- auto *C1 = dyn_cast<ConstantInt>( Operands[1 ]);
2141
- auto *C2 = dyn_cast<ConstantInt> (Operands[2 ]);
2142
- if (!(C0 && C1 && C2))
2183
+ const APInt *C0, *C1, *C2 ;
2184
+ if (! getConstIntOrUndef ( Operands[0 ], C0) ||
2185
+ ! getConstIntOrUndef (Operands[1 ], C1) ||
2186
+ ! getConstIntOrUndef (Operands[ 2 ], C2))
2143
2187
return nullptr ;
2144
2188
2189
+ bool IsRight = IntrinsicID == Intrinsic::fshr;
2190
+ if (!C2)
2191
+ return Operands[IsRight ? 1 : 0 ];
2192
+ if (!C0 && !C1)
2193
+ return UndefValue::get (Ty);
2194
+
2145
2195
// The shift amount is interpreted as modulo the bitwidth. If the shift
2146
2196
// amount is effectively 0, avoid UB due to oversized inverse shift below.
2147
- unsigned BitWidth = C0->getBitWidth ();
2148
- unsigned ShAmt = C2->getValue ().urem (BitWidth);
2149
- bool IsRight = IntrinsicID == Intrinsic::fshr;
2197
+ unsigned BitWidth = C2->getBitWidth ();
2198
+ unsigned ShAmt = C2->urem (BitWidth);
2150
2199
if (!ShAmt)
2151
- return IsRight ? C1 : C0 ;
2200
+ return Operands[ IsRight ? 1 : 0 ] ;
2152
2201
2153
- // (X << ShlAmt) | (Y >> LshrAmt)
2154
- const APInt &X = C0->getValue ();
2155
- const APInt &Y = C1->getValue ();
2202
+ // (C0 << ShlAmt) | (C1 >> LshrAmt)
2156
2203
unsigned LshrAmt = IsRight ? ShAmt : BitWidth - ShAmt;
2157
2204
unsigned ShlAmt = !IsRight ? ShAmt : BitWidth - ShAmt;
2158
- return ConstantInt::get (Ty->getContext (), X.shl (ShlAmt) | Y.lshr (LshrAmt));
2205
+ if (!C0)
2206
+ return ConstantInt::get (Ty, C1->lshr (LshrAmt));
2207
+ if (!C1)
2208
+ return ConstantInt::get (Ty, C0->shl (ShlAmt));
2209
+ return ConstantInt::get (Ty, C0->shl (ShlAmt) | C1->lshr (LshrAmt));
2159
2210
}
2160
2211
2161
2212
return nullptr ;
0 commit comments