[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