[InstCombine] Prevent infinite loop with two shifts (#118806)

The following pattern: `(C2 << X) << C1` will usually be transformed
into `(C2 << C1) << X`, essentially swapping `X` and `C1`.

However, this should only be done when `C1` is an immediate constant,
otherwise thiscan lead to both constants being swapped forever.

This fixes #118798.
This commit is contained in:
Maurice Heumann
2024-12-05 16:57:27 +01:00
committed by GitHub
parent 8a90b5b317
commit 27eaa8a40e
2 changed files with 18 additions and 1 deletions

View File

@@ -427,7 +427,8 @@ Instruction *InstCombinerImpl::commonShiftTransforms(BinaryOperator &I) {
if (Instruction *R = FoldOpIntoSelect(I, SI))
return R;
if (Constant *CUI = dyn_cast<Constant>(Op1))
Constant *CUI;
if (match(Op1, m_ImmConstant(CUI)))
if (Instruction *Res = FoldShiftByConstant(Op0, CUI, I))
return Res;

View File

@@ -0,0 +1,16 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
@c = external constant i8
@c2 = external constant i8
define i64 @testfunc() {
; CHECK-LABEL: @testfunc(
; CHECK-NEXT: [[SHL1:%.*]] = shl nuw i64 1, ptrtoint (ptr @c2 to i64)
; CHECK-NEXT: [[SHL2:%.*]] = shl i64 [[SHL1]], ptrtoint (ptr @c to i64)
; CHECK-NEXT: ret i64 [[SHL2]]
;
%shl1 = shl i64 1, ptrtoint (ptr @c2 to i64)
%shl2 = shl i64 %shl1, ptrtoint (ptr @c to i64)
ret i64 %shl2
}