[llvm] [InstCombine] Try the flipped strictness of predicate in `foldICmpShlConstant` (PR #92773)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Mon May 20 09:50:31 PDT 2024
================
@@ -2414,14 +2414,37 @@ Instruction *InstCombinerImpl::foldICmpShlConstant(ICmpInst &Cmp,
// free on the target. It has the additional benefit of comparing to a
// smaller constant that may be more target-friendly.
unsigned Amt = ShiftAmt->getLimitedValue(TypeBits - 1);
- if (Shl->hasOneUse() && Amt != 0 && C.countr_zero() >= Amt &&
- DL.isLegalInteger(TypeBits - Amt)) {
- Type *TruncTy = IntegerType::get(Cmp.getContext(), TypeBits - Amt);
- if (auto *ShVTy = dyn_cast<VectorType>(ShType))
- TruncTy = VectorType::get(TruncTy, ShVTy->getElementCount());
- Constant *NewC =
- ConstantInt::get(TruncTy, C.ashr(*ShiftAmt).trunc(TypeBits - Amt));
- return new ICmpInst(Pred, Builder.CreateTrunc(X, TruncTy), NewC);
+ if (Shl->hasOneUse() && Amt != 0 && DL.isLegalInteger(TypeBits - Amt)) {
+ auto FoldICmpShlToICmpTrunc = [&](ICmpInst::Predicate Pred,
+ const APInt &C) -> Instruction * {
+ if (C.countr_zero() < Amt)
+ return nullptr;
+ Type *TruncTy = ShType->getWithNewBitWidth(TypeBits - Amt);
+ Constant *NewC =
+ ConstantInt::get(TruncTy, C.ashr(*ShiftAmt).trunc(TypeBits - Amt));
+ return new ICmpInst(
+ Pred, Builder.CreateTrunc(X, TruncTy, "", Shl->hasNoSignedWrap()),
----------------
dtcxzyw wrote:
```
----------------------------------------
define i1 @src_eq_nuw(i32 %x, i32 %c) {
#0:
%cttz = cttz i32 %c, 1
%cond = icmp uge i32 %cttz, 16
assume i1 %cond
%shl = shl nuw i32 %x, 16
%icmp = icmp eq i32 %shl, %c
ret i1 %icmp
}
=>
define i1 @tgt_eq_nuw(i32 %x, i32 %c) {
#0:
%trunc = trunc i32 %x to i16
%ashr_c = ashr i32 %c, 16
%trunc_c = trunc nuw i32 %ashr_c to i16
%icmp = icmp eq i16 %trunc, %trunc_c
ret i1 %icmp
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
i32 %x = #x00000000 (0)
i32 %c = #xbfff0000 (3221159936, -1073807360)
Source:
i32 %cttz = #x00000010 (16)
i1 %cond = #x1 (1)
i32 %shl = #x00000000 (0)
i1 %icmp = #x0 (0)
Target:
i16 %trunc = #x0000 (0)
i32 %ashr_c = #xffffbfff (4294950911, -16385)
i16 %trunc_c = poison
i1 %icmp = poison
Source value: #x0 (0)
Target value: poison
----------------------------------------
define i1 @src_ult_nuw(i32 %x, i32 %c) {
#0:
%cttz = cttz i32 %c, 1
%cond = icmp uge i32 %cttz, 16
assume i1 %cond
%shl = shl nuw i32 %x, 16
%icmp = icmp ult i32 %shl, %c
ret i1 %icmp
}
=>
define i1 @tgt_ult_nuw(i32 %x, i32 %c) {
#0:
%trunc = trunc i32 %x to i16
%ashr_c = ashr i32 %c, 16
%trunc_c = trunc nuw i32 %ashr_c to i16
%icmp = icmp ult i16 %trunc, %trunc_c
ret i1 %icmp
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
i32 %x = #x00000000 (0)
i32 %c = #xbfff0000 (3221159936, -1073807360)
Source:
i32 %cttz = #x00000010 (16)
i1 %cond = #x1 (1)
i32 %shl = #x00000000 (0)
i1 %icmp = #x1 (1)
Target:
i16 %trunc = #x0000 (0)
i32 %ashr_c = #xffffbfff (4294950911, -16385)
i16 %trunc_c = poison
i1 %icmp = poison
Source value: #x1 (1)
Target value: poison
----------------------------------------
define i1 @src_slt_nuw(i32 %x, i32 %c) {
#0:
%cttz = cttz i32 %c, 1
%cond = icmp uge i32 %cttz, 16
assume i1 %cond
%shl = shl nuw i32 %x, 16
%icmp = icmp slt i32 %shl, %c
ret i1 %icmp
}
=>
define i1 @tgt_slt_nuw(i32 %x, i32 %c) {
#0:
%trunc = trunc i32 %x to i16
%ashr_c = ashr i32 %c, 16
%trunc_c = trunc nuw i32 %ashr_c to i16
%icmp = icmp slt i16 %trunc, %trunc_c
ret i1 %icmp
}
Transformation doesn't verify!
ERROR: Target is more poisonous than source
Example:
i32 %x = #x00000000 (0)
i32 %c = #xbfff0000 (3221159936, -1073807360)
Source:
i32 %cttz = #x00000010 (16)
i1 %cond = #x1 (1)
i32 %shl = #x00000000 (0)
i1 %icmp = #x0 (0)
Target:
i16 %trunc = #x0000 (0)
i32 %ashr_c = #xffffbfff (4294950911, -16385)
i16 %trunc_c = poison
i1 %icmp = poison
Source value: #x0 (0)
Target value: poison
```
https://github.com/llvm/llvm-project/pull/92773
More information about the llvm-commits
mailing list