[llvm] 7faa8c6 - [ConstraintElimination] Fix undefined behaviour in shl decomposition

Zain Jaffal via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 9 10:21:24 PST 2023


Author: Zain Jaffal
Date: 2023-03-09T18:17:27Z
New Revision: 7faa8c6ec6d4518663f49b0298c1762d90cb14f5

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

LOG: [ConstraintElimination] Fix undefined behaviour in shl decomposition

Add checks to prevent decomposing constants bigger than 64.
relates to https://github.com/llvm/llvm-project/issues/61127

Reviewed By: fhahn

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
    llvm/test/Transforms/ConstraintElimination/shl.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
index f660e73781d59..ce32507d42493 100644
--- a/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp
@@ -377,7 +377,9 @@ static Decomposition decompose(Value *V,
   }
 
   if (match(V, m_NUWShl(m_Value(Op1), m_ConstantInt(CI))) && canUseSExt(CI)) {
-    int64_t Mult = int64_t(std::pow(int64_t(2), CI->getSExtValue()));
+    if (CI->getSExtValue() < 0 || CI->getSExtValue() >= 64)
+      return {V, IsKnownNonNegative};
+    int64_t Mult = 1 << CI->getSExtValue();
     auto Result = decompose(Op1, Preconditions, IsSigned, DL);
     Result.mul(Mult);
     return Result;

diff  --git a/llvm/test/Transforms/ConstraintElimination/shl.ll b/llvm/test/Transforms/ConstraintElimination/shl.ll
index e11fdacbd5497..5237a346f3d3d 100644
--- a/llvm/test/Transforms/ConstraintElimination/shl.ll
+++ b/llvm/test/Transforms/ConstraintElimination/shl.ll
@@ -1223,3 +1223,55 @@ entry:
   %f.1 = icmp ule i8 %start.add.2.13, %start.shl.4
   ret i1 %f.1
 }
+
+define i1 @shl_overflow(i64 %start) {
+; CHECK-LABEL: @shl_overflow(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[PRE_COND:%.*]] = icmp ugt i64 [[START:%.*]], 0
+; CHECK-NEXT:    br i1 [[PRE_COND]], label [[MAIN:%.*]], label [[EXIT:%.*]]
+; CHECK:       main:
+; CHECK-NEXT:    [[TMP0:%.*]] = shl nuw nsw i64 [[START]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp uge i64 [[TMP0]], [[START]]
+; CHECK-NEXT:    ret i1 [[TMP1]]
+; CHECK:       exit:
+; CHECK-NEXT:    ret i1 false
+;
+entry:
+  %pre.cond = icmp ugt i64 %start, 0
+  br i1 %pre.cond, label %main, label %exit
+
+main:
+  %0 = shl nuw nsw i64 %start, -1
+  %1 = icmp uge i64 %0, %start
+  ret i1 %1
+
+exit:
+  ret i1 0
+}
+
+
+define i1 @shl_overflow_2() {
+; CHECK-LABEL: @shl_overflow_2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SHL_UB:%.*]] = shl nuw nsw i256 0, 64
+; CHECK-NEXT:    [[SHL_CMP:%.*]] = icmp uge i256 [[SHL_UB]], 0
+; CHECK-NEXT:    ret i1 [[SHL_CMP]]
+;
+entry:
+  %shl.ub = shl nuw nsw i256 0, 64
+  %shl.cmp = icmp uge i256 %shl.ub, 0
+  ret i1 %shl.cmp
+}
+
+define i1 @shl_overflow_3() {
+; CHECK-LABEL: @shl_overflow_3(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SHL_UB:%.*]] = shl nuw nsw i256 0, 65
+; CHECK-NEXT:    [[SHL_CMP:%.*]] = icmp uge i256 [[SHL_UB]], 0
+; CHECK-NEXT:    ret i1 [[SHL_CMP]]
+;
+entry:
+  %shl.ub = shl nuw nsw i256 0, 65
+  %shl.cmp = icmp uge i256 %shl.ub, 0
+  ret i1 %shl.cmp
+}


        


More information about the llvm-commits mailing list