}
}
+ // Find out if any arguments are required to be integer constant
+ // expressions.
+ unsigned ICEArguments = 0;
+ ASTContext::GetBuiltinTypeError Error;
+ getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
+ assert(Error == ASTContext::GE_None && "Should not codegen an error");
+
SmallVector<Value*, 4> Ops;
llvm::Value *Align = nullptr;
for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
continue;
}
}
- Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+ if ((ICEArguments & (1 << i)) == 0) {
+ Ops.push_back(EmitScalarExpr(E->getArg(i)));
+ } else {
+ // If this is required to be a constant, constant fold it so that we know
+ // that the generated intrinsic gets a ConstantInt.
+ llvm::APSInt Result;
+ bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
+ assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
+ Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
+ }
}
switch (BuiltinID) {
return Builder.CreateCall(F, {Arg0, Arg1});
}
+ // Find out if any arguments are required to be integer constant
+ // expressions.
+ unsigned ICEArguments = 0;
+ ASTContext::GetBuiltinTypeError Error;
+ getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
+ assert(Error == ASTContext::GE_None && "Should not codegen an error");
+
llvm::SmallVector<Value*, 4> Ops;
- for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++)
- Ops.push_back(EmitScalarExpr(E->getArg(i)));
+ for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
+ if ((ICEArguments & (1 << i)) == 0) {
+ Ops.push_back(EmitScalarExpr(E->getArg(i)));
+ } else {
+ // If this is required to be a constant, constant fold it so that we know
+ // that the generated intrinsic gets a ConstantInt.
+ llvm::APSInt Result;
+ bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
+ assert(IsConst && "Constant arg isn't actually constant?");
+ (void)IsConst;
+ Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
+ }
+ }
auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
private:
TypeSpec TS;
- bool Float, Signed, Void, Poly, Constant, Pointer;
+ bool Float, Signed, Immediate, Void, Poly, Constant, Pointer;
// ScalarForMangling and NoManglingQ are really not suited to live here as
// they are not related to the type. But they live in the TypeSpec (not the
// prototype), so this is really the only place to store them.
public:
Type()
- : Float(false), Signed(false), Void(true), Poly(false), Constant(false),
- Pointer(false), ScalarForMangling(false), NoManglingQ(false),
- Bitwidth(0), ElementBitwidth(0), NumVectors(0) {}
+ : Float(false), Signed(false), Immediate(false), Void(true), Poly(false),
+ Constant(false), Pointer(false), ScalarForMangling(false),
+ NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {}
Type(TypeSpec TS, char CharMod)
- : TS(TS), Float(false), Signed(false), Void(false), Poly(false),
- Constant(false), Pointer(false), ScalarForMangling(false),
+ : TS(TS), Float(false), Signed(false), Immediate(false), Void(false),
+ Poly(false), Constant(false), Pointer(false), ScalarForMangling(false),
NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {
applyModifier(CharMod);
}
bool isFloating() const { return Float; }
bool isInteger() const { return !Float && !Poly; }
bool isSigned() const { return Signed; }
+ bool isImmediate() const { return Immediate; }
bool isScalar() const { return NumVectors == 0; }
bool isVector() const { return NumVectors > 0; }
bool isFloat() const { return Float && ElementBitwidth == 32; }
Float = false;
Poly = false;
Signed = Sign;
+ Immediate = false;
+ ElementBitwidth = ElemWidth;
+ }
+ void makeImmediate(unsigned ElemWidth) {
+ Float = false;
+ Poly = false;
+ Signed = true;
+ Immediate = true;
ElementBitwidth = ElemWidth;
}
void makeScalar() {
else if (isInteger() && !Pointer && !Signed)
S = "U" + S;
+ // Constant indices are "int", but have the "constant expression" modifier.
+ if (isImmediate()) {
+ assert(isInteger() && isSigned());
+ S = "I" + S;
+ }
+
if (isScalar()) {
if (Constant) S += "C";
if (Pointer) S += "*";
ElementBitwidth = Bitwidth = 32;
NumVectors = 0;
Signed = true;
+ Immediate = true;
break;
case 'l':
Float = false;
ElementBitwidth = Bitwidth = 64;
NumVectors = 0;
Signed = false;
+ Immediate = true;
break;
case 'z':
ElementBitwidth /= 2;
if (LocalCK == ClassI)
T.makeSigned();
- // Constant indices are always just "int".
if (hasImmediate() && getImmediateIdx() == I)
- T.makeInteger(32, true);
+ T.makeImmediate(32);
S += T.builtin_str();
}