[llvm-commits] [dragonegg] r140527 - /dragonegg/trunk/src/Convert.cpp
Duncan Sands
baldrick at free.fr
Mon Sep 26 05:21:07 PDT 2011
Author: baldrick
Date: Mon Sep 26 07:21:07 2011
New Revision: 140527
URL: http://llvm.org/viewvc/llvm-project?rev=140527&view=rev
Log:
Don't crash on ABS_EXPR with a 128 bit floating point operand.
Modified:
dragonegg/trunk/src/Convert.cpp
Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=140527&r1=140526&r2=140527&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Mon Sep 26 07:21:07 2011
@@ -124,7 +124,8 @@
}
/// SelectFPName - Helper for choosing a name depending on whether a floating
-/// point type is float, double or long double.
+/// point type is float, double or long double. Returns an empty string for
+/// other types, such as the x86 128 bit floating point type.
static StringRef SelectFPName(tree type, StringRef FloatName,
StringRef DoubleName, StringRef LongDoubleName) {
assert(SCALAR_FLOAT_TYPE_P(type) && "Expected a floating point type!");
@@ -132,9 +133,9 @@
return FloatName;
if (TYPE_MODE(type) == TYPE_MODE(double_type_node))
return DoubleName;
- assert(TYPE_MODE(type) == TYPE_MODE(long_double_type_node) &&
- "Unknown floating point type!");
- return LongDoubleName;
+ if (TYPE_MODE(type) == TYPE_MODE(long_double_type_node))
+ return LongDoubleName;
+ return StringRef();
}
@@ -4607,6 +4608,7 @@
// First call the appropriate version of "ceil".
tree op = gimple_call_arg(stmt, 0);
StringRef Name = SelectFPName(TREE_TYPE(op), "ceilf", "ceil", "ceill");
+ assert(!Name.empty() && "Unsupported floating point type!");
CallInst *Call = EmitSimpleCall(Name, TREE_TYPE(op), op, NULL);
Call->setDoesNotThrow();
Call->setDoesNotAccessMemory();
@@ -4626,6 +4628,7 @@
// First call the appropriate version of "floor".
tree op = gimple_call_arg(stmt, 0);
StringRef Name = SelectFPName(TREE_TYPE(op), "floorf", "floor", "floorl");
+ assert(!Name.empty() && "Unsupported floating point type!");
CallInst *Call = EmitSimpleCall(Name, TREE_TYPE(op), op, NULL);
Call->setDoesNotThrow();
Call->setDoesNotAccessMemory();
@@ -4647,6 +4650,7 @@
tree arg = gimple_call_arg(stmt, 0);
tree arg_type = TREE_TYPE(arg);
StringRef Name = SelectFPName(arg_type, "sincosf", "sincos", "sincosl");
+ assert(!Name.empty() && "Unsupported floating point type!");
// Create stack slots to store the real (cos) and imaginary (sin) parts in.
Value *Val = EmitRegister(arg);
@@ -4693,6 +4697,7 @@
tree arg = gimple_call_arg(stmt, 0);
tree arg_type = TREE_TYPE(arg);
StringRef Name = SelectFPName(arg_type, "cexpf", "cexp", "cexpl");
+ assert(!Name.empty() && "Unsupported floating point type!");
// Get the GCC and LLVM function types for cexp.
tree cplx_type = gimple_call_return_type(stmt);
@@ -6275,7 +6280,9 @@
Value *Cmp = Builder.CreateICmp(pred, Op,
Constant::getNullValue(Op->getType()), "abscond");
return Builder.CreateSelect(Cmp, Op, OpN, Op->getName()+"abs");
- } else if (TREE_CODE(TREE_TYPE(op)) == VECTOR_TYPE) {
+ }
+
+ if (TREE_CODE(TREE_TYPE(op)) == VECTOR_TYPE) {
// Clear the sign bits.
Value *Op = EmitRegister(op);
VectorType *VecTy = cast<VectorType>(Op->getType());
@@ -6297,10 +6304,29 @@
// Turn FP abs into fabs/fabsf.
StringRef Name = SelectFPName(TREE_TYPE(op), "fabsf", "fabs", "fabsl");
- CallInst *Call = EmitSimpleCall(Name, TREE_TYPE(op), op, NULL);
- Call->setDoesNotThrow();
- Call->setDoesNotAccessMemory();
- return Call;
+ if (!Name.empty()) {
+ CallInst *Call = EmitSimpleCall(Name, TREE_TYPE(op), op, NULL);
+ Call->setDoesNotThrow();
+ Call->setDoesNotAccessMemory();
+ return Call;
+ }
+
+ // Otherwise clear the sign bit.
+ Value *Op = EmitRegister(op);
+ Type *Ty = Op->getType();
+
+ // Mask = ~(1 << (Bits-1)).
+ unsigned Bits = Ty->getPrimitiveSizeInBits();
+ Type *IntTy = IntegerType::get(Context, Bits);
+ APInt API = APInt::getAllOnesValue(Bits);
+ API.clearBit(Bits-1);
+ Constant *Mask = ConstantInt::get(IntTy, API);
+
+ // Zap the sign bit.
+ Op = Builder.CreateBitCast(Op, IntTy);
+ Op = Builder.CreateAnd(Op, Mask);
+ Op = Builder.CreateBitCast(Op, Ty);
+ return Op;
}
Value *TreeToLLVM::EmitReg_BIT_NOT_EXPR(tree op) {
More information about the llvm-commits
mailing list