[clang] [Headers][X86] VisitCallExpr constexpr immediate shifts (#154293) (PR #155542)

Simon Pilgrim via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 29 00:53:00 PDT 2025


================
@@ -11644,64 +11679,181 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
 
     for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
       APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt();
-      APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt();
-      switch (E->getBuiltinCallee()) {
-      case Builtin::BI__builtin_elementwise_add_sat:
-        ResultElements.push_back(APValue(
-            APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS),
-                   DestUnsigned)));
-        break;
-      case Builtin::BI__builtin_elementwise_sub_sat:
-        ResultElements.push_back(APValue(
-            APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS),
-                   DestUnsigned)));
-        break;
-      case clang::X86::BI__builtin_ia32_pmulhuw128:
-      case clang::X86::BI__builtin_ia32_pmulhuw256:
-      case clang::X86::BI__builtin_ia32_pmulhuw512:
-        ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhu(LHS, RHS),
-                                                /*isUnsigned=*/true)));
-        break;
-      case clang::X86::BI__builtin_ia32_pmulhw128:
-      case clang::X86::BI__builtin_ia32_pmulhw256:
-      case clang::X86::BI__builtin_ia32_pmulhw512:
-        ResultElements.push_back(APValue(APSInt(llvm::APIntOps::mulhs(LHS, RHS),
-                                                /*isUnsigned=*/false)));
-        break;
-      case clang::X86::BI__builtin_ia32_psllv2di:
-      case clang::X86::BI__builtin_ia32_psllv4di:
-      case clang::X86::BI__builtin_ia32_psllv4si:
-      case clang::X86::BI__builtin_ia32_psllv8si:
-        if (RHS.uge(RHS.getBitWidth())) {
-          ResultElements.push_back(
-              APValue(APSInt(APInt::getZero(RHS.getBitWidth()), DestUnsigned)));
+
+      if (SourceRHS.isInt()) {
+        uint64_t LaneWidth = 0;
+        bool IsLeftShift = false;
+        bool IsRightShift = false;
+        bool IsArithmeticRightShift = false;
+
+        switch (E->getBuiltinCallee()) {
+        case clang::X86::BI__builtin_ia32_psllwi128:
+        case clang::X86::BI__builtin_ia32_psllwi256:
+        case clang::X86::BI__builtin_ia32_psllwi512:
+          IsLeftShift = true;
+          LaneWidth = 16;
+          break;
+        case clang::X86::BI__builtin_ia32_pslldi128:
+        case clang::X86::BI__builtin_ia32_pslldi256:
+        case clang::X86::BI__builtin_ia32_pslldi512:
+          IsLeftShift = true;
+          LaneWidth = 32;
+          break;
+        case clang::X86::BI__builtin_ia32_psllqi128:
+        case clang::X86::BI__builtin_ia32_psllqi256:
+        case clang::X86::BI__builtin_ia32_psllqi512:
+          IsLeftShift = true;
+          LaneWidth = 64;
           break;
+
+        case clang::X86::BI__builtin_ia32_psrlwi128:
+        case clang::X86::BI__builtin_ia32_psrlwi256:
+        case clang::X86::BI__builtin_ia32_psrlwi512:
+          IsRightShift = true;
+          LaneWidth = 16;
+          break;
+        case clang::X86::BI__builtin_ia32_psrldi128:
+        case clang::X86::BI__builtin_ia32_psrldi256:
+        case clang::X86::BI__builtin_ia32_psrldi512:
+          IsRightShift = true;
+          LaneWidth = 32;
+          break;
+        case clang::X86::BI__builtin_ia32_psrlqi128:
+        case clang::X86::BI__builtin_ia32_psrlqi256:
+        case clang::X86::BI__builtin_ia32_psrlqi512:
+          IsRightShift = true;
+          LaneWidth = 64;
+          break;
+
+        case clang::X86::BI__builtin_ia32_psrawi128:
+        case clang::X86::BI__builtin_ia32_psrawi256:
+        case clang::X86::BI__builtin_ia32_psrawi512:
+          IsArithmeticRightShift = true;
+          LaneWidth = 16;
+          break;
+        case clang::X86::BI__builtin_ia32_psradi128:
+        case clang::X86::BI__builtin_ia32_psradi256:
+        case clang::X86::BI__builtin_ia32_psradi512:
+          IsArithmeticRightShift = true;
+          LaneWidth = 32;
+          break;
+        case clang::X86::BI__builtin_ia32_psraqi128:
+        case clang::X86::BI__builtin_ia32_psraqi256:
+        case clang::X86::BI__builtin_ia32_psraqi512:
+          IsArithmeticRightShift = true;
+          LaneWidth = 64;
+          break;
+
+        default:
+          llvm_unreachable("Unexpected builtin callee");
         }
-        ResultElements.push_back(
-            APValue(APSInt(LHS.shl(RHS.getZExtValue()), DestUnsigned)));
-        break;
-      case clang::X86::BI__builtin_ia32_psrav4si:
-      case clang::X86::BI__builtin_ia32_psrav8si:
-        if (RHS.uge(RHS.getBitWidth())) {
+
+        const APSInt RHS = SourceRHS.getInt();
+        const auto ShiftAmount = RHS.getZExtValue();
+        APInt ResultOut;
+        if (IsArithmeticRightShift) {
+          ResultOut = LHS.ashr(std::min(ShiftAmount, LaneWidth));
+        } else if (ShiftAmount >= LaneWidth) {
+          ResultOut = APInt(LaneWidth, 0);
+        } else if (IsLeftShift) {
+          ResultOut = LHS.shl(ShiftAmount);
+        } else if (IsRightShift) {
+          ResultOut = LHS.lshr(ShiftAmount);
+        } else {
+          llvm_unreachable("Invalid shift type");
+        }
+        ResultElements.push_back(APValue(APSInt(
+            std::move(ResultOut),
+            /*isUnsigned=*/DestEltTy->isUnsignedIntegerOrEnumerationType())));
+      } else {
+        APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt();
----------------
RKSimon wrote:

You can reduce the diff and avoid the else case if you continue at the end of the SourceRHS.isInt() block

https://github.com/llvm/llvm-project/pull/155542


More information about the cfe-commits mailing list