[clang] f6267d3 - [clang][CGExprConstant] handle implicit widening/narrowing Int-to-Int casts

Nick Desaulniers via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 7 14:57:36 PDT 2023


Author: Nick Desaulniers
Date: 2023-08-07T14:57:25-07:00
New Revision: f6267d3b98c11b50bf24946f21c6646d2d3f6fa8

URL: https://github.com/llvm/llvm-project/commit/f6267d3b98c11b50bf24946f21c6646d2d3f6fa8
DIFF: https://github.com/llvm/llvm-project/commit/f6267d3b98c11b50bf24946f21c6646d2d3f6fa8.diff

LOG: [clang][CGExprConstant] handle implicit widening/narrowing Int-to-Int casts

Consider the following statements:
    long x = 1;
    short y = 1;

With the following AST:
    |-VarDecl 0x55d289973730 <x.c:1:1, col:10> col:6 x 'long' cinit
    | `-ImplicitCastExpr 0x55d289973800 <col:10> 'long' <IntegralCast>
    |   `-IntegerLiteral 0x55d2899737e0 <col:10> 'int' 1
    `-VarDecl 0x55d289973830 <line:2:1, col:11> col:7 y 'short' cinit
      `-ImplicitCastExpr 0x55d2899738b8 <col:11> 'short' <IntegralCast>
        `-IntegerLiteral 0x55d289973898 <col:11> 'int' 1

Sign or Zero extend or truncate based on the source signedness and
destination width.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D156466

Added: 
    

Modified: 
    clang/lib/CodeGen/CGExprConstant.cpp
    clang/test/CodeGen/global-init.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index e482b57eb144d7..b0f52066daeeca 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -1139,6 +1139,24 @@ class ConstExprEmitter :
     case CK_IntToOCLSampler:
       llvm_unreachable("global sampler variables are not generated");
 
+    case CK_IntegralCast: {
+      QualType FromType = subExpr->getType();
+      // See also HandleIntToIntCast in ExprConstant.cpp
+      if (FromType->isIntegerType())
+        if (llvm::Constant *C = Visit(subExpr, FromType))
+          if (auto *CI = dyn_cast<llvm::ConstantInt>(C)) {
+            unsigned SrcWidth = CGM.getContext().getIntWidth(FromType);
+            unsigned DstWidth = CGM.getContext().getIntWidth(destType);
+            if (DstWidth == SrcWidth)
+              return CI;
+            llvm::APInt A = FromType->isSignedIntegerType()
+                                ? CI->getValue().sextOrTrunc(DstWidth)
+                                : CI->getValue().zextOrTrunc(DstWidth);
+            return llvm::ConstantInt::get(CGM.getLLVMContext(), A);
+          }
+      return nullptr;
+    }
+
     case CK_Dependent: llvm_unreachable("saw dependent cast!");
 
     case CK_BuiltinFnToFnPtr:
@@ -1191,7 +1209,6 @@ class ConstExprEmitter :
     case CK_IntegralComplexToFloatingComplex:
     case CK_PointerToIntegral:
     case CK_PointerToBoolean:
-    case CK_IntegralCast:
     case CK_BooleanToSignedIntegral:
     case CK_IntegralToPointer:
     case CK_IntegralToBoolean:

diff  --git a/clang/test/CodeGen/global-init.c b/clang/test/CodeGen/global-init.c
index a69f0288561104..fbf3c973ad9755 100644
--- a/clang/test/CodeGen/global-init.c
+++ b/clang/test/CodeGen/global-init.c
@@ -49,6 +49,11 @@ struct K {
 // CHECK: @yuv_types ={{.*}} global [4 x [6 x i8]] {{\[}}[6 x i8] c"4:0:0\00", [6 x i8] c"4:2:0\00", [6 x i8] c"4:2:2\00", [6 x i8] c"4:4:4\00"]
 char yuv_types[4][6]= {"4:0:0","4:2:0","4:2:2","4:4:4"};
 
+unsigned long long x = -1000;
+// CHECK: @x ={{.*}} global i64 -1000
+unsigned long long uint_max = 4294967295u;
+// CHECK: @uint_max ={{.*}} global i64 4294967295
+
 
 // NOTE: tentative definitions are processed at the end of the translation unit.
 


        


More information about the cfe-commits mailing list