From 88a569a9781e0472a1f1c392f6c94ed0c068d946 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 24 Mar 2012 14:43:42 +0000 Subject: [PATCH] Revert r153360 (and r153380), "Second part of PR12251. Produce the range metadata in clang for booleans and". For i686 targets (eg. cygwin), I saw "Range must not be empty!" in verifier. It produces (i32)[0x80000000:0x80000000) from (uint64_t)[0xFFFFFFFF80000000ULL:0x0000000080000000ULL), for signed i32 on MDNode::Range. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153382 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExpr.cpp | 69 +++---------------- lib/CodeGen/CodeGenFunction.h | 1 - test/CodeGen/pr12251.c | 11 ---- test/CodeGenCXX/pr12251.cpp | 121 ---------------------------------- 4 files changed, 8 insertions(+), 194 deletions(-) delete mode 100644 test/CodeGen/pr12251.c delete mode 100644 test/CodeGenCXX/pr12251.cpp diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 5a847a3b96..30e3e7ad2c 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -860,61 +860,6 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) { lvalue.getType(), lvalue.getTBAAInfo()); } -static bool hasBooleanRepresentation(QualType Ty) { - if (Ty->isBooleanType()) - return true; - - if (const EnumType *ET = Ty->getAs()) - return ET->getDecl()->getIntegerType()->isBooleanType(); - - return false; -} - -llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { - const EnumType *ET = Ty->getAs(); - bool IsRegularCPlusPlusEnum = getLangOpts().CPlusPlus && ET && - !ET->getDecl()->isFixed(); - bool IsBool = hasBooleanRepresentation(Ty); - llvm::Type *LTy; - if (!IsBool && !IsRegularCPlusPlusEnum) - return NULL; - - uint64_t Min; - uint64_t End; - if (IsBool) { - Min = 0; - End = 2; - LTy = Int8Ty; - } else { - const EnumDecl *ED = ET->getDecl(); - LTy = ConvertTypeForMem(ED->getIntegerType()); - unsigned NumNegativeBits = ED->getNumNegativeBits(); - unsigned NumPositiveBits = ED->getNumPositiveBits(); - - if (NumNegativeBits) { - unsigned NumBits = std::max(NumNegativeBits, NumPositiveBits + 1); - assert(NumBits <= 64); - End = 1ULL << (NumBits - 1); - Min = -End; - } else { - assert(NumPositiveBits <= 64); - if (NumPositiveBits == 64) - return NULL; - End = 1ULL << NumPositiveBits; - Min = 0; - } - } - - assert(End != Min); - llvm::Value *LowAndHigh[2]; - LowAndHigh[0] = llvm::ConstantInt::get(LTy, Min); - LowAndHigh[1] = llvm::ConstantInt::get(LTy, End); - - llvm::LLVMContext &C = getLLVMContext(); - llvm::MDNode *Range = llvm::MDNode::get(C, LowAndHigh); - return Range; -} - llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo) { @@ -929,16 +874,18 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, if (Ty->isAtomicType()) Load->setAtomic(llvm::SequentiallyConsistent); - if (CGM.getCodeGenOpts().OptimizationLevel > 0) - if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) - Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); - return EmitFromMemory(Load, Ty); } +static bool isBooleanUnderlyingType(QualType Ty) { + if (const EnumType *ET = dyn_cast(Ty)) + return ET->getDecl()->getIntegerType()->isBooleanType(); + return false; +} + llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { // Bool has a different representation in memory than in registers. - if (hasBooleanRepresentation(Ty)) { + if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) { // This should really always be an i1, but sometimes it's already // an i8, and it's awkward to track those cases down. if (Value->getType()->isIntegerTy(1)) @@ -951,7 +898,7 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) { llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) { // Bool has a different representation in memory than in registers. - if (hasBooleanRepresentation(Ty)) { + if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) { assert(Value->getType()->isIntegerTy(8) && "memory rep of bool not i8"); return Builder.CreateTrunc(Value, Builder.getInt1Ty(), "tobool"); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 85cbd143d8..e0e6501b19 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2522,7 +2522,6 @@ public: unsigned AccuracyD = 1); private: - llvm::MDNode *getRangeForLoadFromType(QualType Ty); void EmitReturnOfRValue(RValue RV, QualType Ty); /// ExpandTypeFromArgs - Reconstruct a structure of type \arg Ty diff --git a/test/CodeGen/pr12251.c b/test/CodeGen/pr12251.c deleted file mode 100644 index a644bb79da..0000000000 --- a/test/CodeGen/pr12251.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -o - | FileCheck %s - -enum e1 {e1_a = -1 }; -enum e1 g1(enum e1 *x) { - return *x; -} - -// CHECK: define i32 @g1 -// CHECK: load i32* %x, align 4 -// CHECK-NOT: range -// CHECK: ret diff --git a/test/CodeGenCXX/pr12251.cpp b/test/CodeGenCXX/pr12251.cpp deleted file mode 100644 index c2a8d6fa23..0000000000 --- a/test/CodeGenCXX/pr12251.cpp +++ /dev/null @@ -1,121 +0,0 @@ -// RUN: %clang_cc1 %s -emit-llvm -O1 -relaxed-aliasing -std=c++11 -o - | FileCheck %s - -bool f(bool *x) { - return *x; -} -// CHECK: define zeroext i1 @_Z1fPb -// CHECK: load i8* %{{.*}}, align 1, !range !0 - -enum e1 { }; -e1 g1(e1 *x) { - return *x; -} -// CHECK: define i32 @_Z2g1P2e1 -// CHECK: load i32* %x, align 4, !range !1 - -enum e2 { e2_a = 0 }; -e2 g2(e2 *x) { - return *x; -} -// CHECK: define i32 @_Z2g2P2e2 -// CHECK: load i32* %x, align 4, !range !1 - -enum e3 { e3_a = 16 }; -e3 g3(e3 *x) { - return *x; -} -// CHECK: define i32 @_Z2g3P2e3 -// CHECK: load i32* %x, align 4, !range !2 - -enum e4 { e4_a = -16}; -e4 g4(e4 *x) { - return *x; -} -// CHECK: define i32 @_Z2g4P2e4 -// CHECK: load i32* %x, align 4, !range !3 - -enum e5 { e5_a = -16, e5_b = 16}; -e5 g5(e5 *x) { - return *x; -} -// CHECK: define i32 @_Z2g5P2e5 -// CHECK: load i32* %x, align 4, !range !4 - -enum e6 { e6_a = -1 }; -e6 g6(e6 *x) { - return *x; -} -// CHECK: define i32 @_Z2g6P2e6 -// CHECK: load i32* %x, align 4, !range !5 - -enum e7 { e7_a = -16, e7_b = 2}; -e7 g7(e7 *x) { - return *x; -} -// CHECK: define i32 @_Z2g7P2e7 -// CHECK: load i32* %x, align 4, !range !3 - -enum e8 { e8_a = -17}; -e8 g8(e8 *x) { - return *x; -} -// CHECK: define i32 @_Z2g8P2e8 -// CHECK: load i32* %x, align 4, !range !4 - -enum e9 { e9_a = 17}; -e9 g9(e9 *x) { - return *x; -} -// CHECK: define i32 @_Z2g9P2e9 -// CHECK: load i32* %x, align 4, !range !2 - -enum e10 { e10_a = -16, e10_b = 32}; -e10 g10(e10 *x) { - return *x; -} -// CHECK: define i32 @_Z3g10P3e10 -// CHECK: load i32* %x, align 4, !range !6 - -enum e11 {e11_a = 4294967296 }; -enum e11 g11(enum e11 *x) { - return *x; -} -// CHECK: define i64 @_Z3g11P3e11 -// CHECK: load i64* %x, align {{[84]}}, !range !7 - -enum e12 {e12_a = 9223372036854775808U }; -enum e12 g12(enum e12 *x) { - return *x; -} -// CHECK: define i64 @_Z3g12P3e12 -// CHECK: load i64* %x, align {{[84]}} -// CHECK-NOT: range -// CHECK: ret - -enum e13 : char {e13_a = -1 }; -e13 g13(e13 *x) { - return *x; -} -// CHECK: define signext i8 @_Z3g13P3e13 -// CHECK: load i8* %x, align 1 -// CHECK-NOT: range -// CHECK: ret - -enum class e14 {e14_a = 1}; -e14 g14(e14 *x) { - return *x; -} -// CHECK: define i32 @_Z3g14P3e14 -// CHECK: load i32* %x, align 4 -// CHECK-NOT: range -// CHECK: ret - - -// CHECK: !0 = metadata !{i8 0, i8 2} -// CHECK: !1 = metadata !{i32 0, i32 1} -// CHECK: !2 = metadata !{i32 0, i32 32} -// CHECK: !3 = metadata !{i32 -16, i32 16} -// CHECK: !4 = metadata !{i32 -32, i32 32} -// CHECK: !5 = metadata !{i32 -1, i32 1} -// CHECK: !6 = metadata !{i32 -64, i32 64} -// CHECK: !7 = metadata !{i64 0, i64 8589934592} -- 2.40.0