[llvm] daf897d - [IR] Check for SignedMin/-1 division in canTrap() (PR56038)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 17 02:25:18 PDT 2022


Author: Nikita Popov
Date: 2022-06-17T11:25:11+02:00
New Revision: daf897d559fcc4fdc88812941aba83ab05463e11

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

LOG: [IR] Check for SignedMin/-1 division in canTrap() (PR56038)

In addition to division by zero, signed division also traps for
SignedMin / -1. This was handled in isSafeToSpeculativelyExecute(),
but not in Constant::canTrap().

Added: 
    

Modified: 
    llvm/lib/IR/Constants.cpp
    llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index 139ff53258990..ef39d65d7f0d9 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -587,14 +587,19 @@ static bool canTrapImpl(const Constant *C,
   switch (CE->getOpcode()) {
   default:
     return false;
-  case Instruction::UDiv:
   case Instruction::SDiv:
-  case Instruction::URem:
   case Instruction::SRem:
-    // Div and rem can trap if the RHS is not known to be non-zero.
-    if (!isa<ConstantInt>(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue())
+    // Signed div/rem can trap for SignedMin / -1.
+    if (!CE->getOperand(0)->isNotMinSignedValue() &&
+        (!isa<ConstantInt>(CE->getOperand(1)) ||
+         CE->getOperand(1)->isAllOnesValue()))
       return true;
-    return false;
+    LLVM_FALLTHROUGH;
+  case Instruction::UDiv:
+  case Instruction::URem:
+    // Div and rem can trap if the RHS is not known to be non-zero.
+    return !isa<ConstantInt>(CE->getOperand(1)) ||
+           CE->getOperand(1)->isNullValue();
   }
 }
 

diff  --git a/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll b/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll
index ce4eca16bfdf3..0f895a512f445 100644
--- a/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll
+++ b/llvm/test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll
@@ -89,3 +89,83 @@ end:
   %phi = phi <1 x i64> [ zeroinitializer, %entry ], [ <i64 srem (i64 1, i64 ptrtoint (i32* @g to i64))>, %if ]
   ret <1 x i64> %phi
 }
+
+define i64 @pt56038_sdiv_minus_one(i1 %c) {
+; CHECK-LABEL: @pt56038_sdiv_minus_one(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -1), [[IF]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret i64 [[PHI]]
+;
+entry:
+  br i1 %c, label %if, label %end
+
+if:
+  br label %end
+
+end:
+  %phi = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -1), %if ], [ 0, %entry ]
+  ret i64 %phi
+}
+
+define i64 @pt56038_srem_not_minus_one(i1 %c) {
+; CHECK-LABEL: @pt56038_srem_not_minus_one(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i64 sdiv (i64 ptrtoint (i32* @g to i64), i64 -2), i64 0
+; CHECK-NEXT:    ret i64 [[SPEC_SELECT]]
+;
+entry:
+  br i1 %c, label %if, label %end
+
+if:
+  br label %end
+
+end:
+  %phi = phi i64 [ sdiv (i64 ptrtoint (i32* @g to i64), i64 -2), %if ], [ 0, %entry ]
+  ret i64 %phi
+}
+
+define i64 @pt56038_sdiv_signed_min(i1 %c) {
+; CHECK-LABEL: @pt56038_sdiv_signed_min(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ sdiv (i64 -9223372036854775808, i64 ptrtoint (i32* @g to i64)), [[IF]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret i64 [[PHI]]
+;
+entry:
+  br i1 %c, label %if, label %end
+
+if:
+  br label %end
+
+end:
+  %phi = phi i64 [ sdiv (i64 -9223372036854775808, i64 ptrtoint (i32* @g to i64)), %if ], [ 0, %entry ]
+  ret i64 %phi
+}
+
+define i64 @pt56038_sdiv_not_signed_min_but_maybe_div_by_zero(i1 %c) {
+; CHECK-LABEL: @pt56038_sdiv_not_signed_min_but_maybe_div_by_zero(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br i1 [[C:%.*]], label [[IF:%.*]], label [[END:%.*]]
+; CHECK:       if:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ sdiv (i64 -9223372036854775807, i64 ptrtoint (i32* @g to i64)), [[IF]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret i64 [[PHI]]
+;
+entry:
+  br i1 %c, label %if, label %end
+
+if:
+  br label %end
+
+end:
+  %phi = phi i64 [ sdiv (i64 -9223372036854775807, i64 ptrtoint (i32* @g to i64)), %if ], [ 0, %entry ]
+  ret i64 %phi
+}


        


More information about the llvm-commits mailing list