Skip to content

Commit 76c69ca

Browse files
authored
[ValueTracking] Bail out on non-immediate constant expressions (#168084)
In #165748 constant expressions were allowed in `collectPossibleValues` because we are still using insertelement + shufflevector idioms to represent a scalable vector splat. However, it also accepts some unresolved constants like ptrtoint of globals or pointer difference between two globals. Absolutely we can ask the user to check this case with the constant folding API. However, since we don't observe the real-world usefulness of handling constant expressions, I decide to be more conservative and only handle immediate constants in the helper function. With this patch, we don't need to touch the SimplifyCFG part, as the values can only be either ConstantInt or undef/poison values (NB: switch on undef condition is UB). Fix the miscompilation reported by #165748 (comment)
1 parent 4cd8c11 commit 76c69ca

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,8 +1024,8 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
10241024
LLVM_ABI Value *stripNullTest(Value *V);
10251025
LLVM_ABI const Value *stripNullTest(const Value *V);
10261026

1027-
/// Enumerates all possible values of V and inserts them into the set \p
1028-
/// Constants. If \p AllowUndefOrPoison is false, it fails when V may contain
1027+
/// Enumerates all possible immediate values of V and inserts them into the set
1028+
/// \p Constants. If \p AllowUndefOrPoison is false, it fails when V may contain
10291029
/// undef/poison elements. Returns true if the result is complete. Otherwise,
10301030
/// the result is incomplete (more than MaxCount values).
10311031
/// NOTE: The constant values are not distinct.

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10504,7 +10504,8 @@ bool llvm::collectPossibleValues(const Value *V,
1050410504
SmallPtrSet<const Instruction *, 8> Visited;
1050510505
SmallVector<const Instruction *, 8> Worklist;
1050610506
auto Push = [&](const Value *V) -> bool {
10507-
if (auto *C = dyn_cast<Constant>(V)) {
10507+
Constant *C;
10508+
if (match(const_cast<Value *>(V), m_ImmConstant(C))) {
1050810509
if (!AllowUndefOrPoison && !isGuaranteedNotToBeUndefOrPoison(C))
1050910510
return false;
1051010511
// Check existence first to avoid unnecessary allocations.

llvm/test/Transforms/SimplifyCFG/switch-on-const.ll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,36 @@ default:
280280
ret void
281281
}
282282

283+
@G = constant i16 zeroinitializer, align 1
284+
285+
; Make sure we don't remove edges when the condition is a unresolved constant expression.
286+
287+
define i16 @switch_on_nonimmediate_constant_expr() {
288+
; CHECK-LABEL: @switch_on_nonimmediate_constant_expr(
289+
; CHECK-NEXT: entry:
290+
; CHECK-NEXT: [[SWITCH_SELECTCMP:%.*]] = icmp eq i32 ptrtoint (ptr @G to i32), 2
291+
; CHECK-NEXT: [[SWITCH_SELECT:%.*]] = select i1 [[SWITCH_SELECTCMP]], i16 456, i16 789
292+
; CHECK-NEXT: [[SWITCH_SELECTCMP1:%.*]] = icmp eq i32 ptrtoint (ptr @G to i32), 1
293+
; CHECK-NEXT: [[SWITCH_SELECT2:%.*]] = select i1 [[SWITCH_SELECTCMP1]], i16 123, i16 [[SWITCH_SELECT]]
294+
; CHECK-NEXT: ret i16 [[SWITCH_SELECT2]]
295+
;
296+
entry:
297+
switch i32 ptrtoint (ptr @G to i32), label %sw.default [
298+
i32 1, label %sw.bb
299+
i32 2, label %sw.bb1
300+
]
301+
302+
sw.bb:
303+
ret i16 123
304+
305+
sw.bb1:
306+
ret i16 456
307+
308+
sw.default:
309+
ret i16 789
310+
}
311+
312+
283313
declare void @llvm.trap() nounwind noreturn
284314
declare void @bees.a() nounwind
285315
declare void @bees.b() nounwind

0 commit comments

Comments
 (0)