Skip to content
Merged
8 changes: 8 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,14 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
Value *And = Builder.CreateAnd(X, MaskC);
return new ICmpInst(ICmpInst::ICMP_NE, And, Zero);
}

if (match(Src, m_AShr(m_Value(X), m_SpecificInt(SrcWidth - 1))) ||
match(Src, m_LShr(m_Value(X), m_SpecificInt(SrcWidth - 1)))) {
// trunc (ashr X, BW-1) to i1 --> icmp slt X, 0
// trunc (lshr X, BW-1) to i1 --> icmp slt X, 0
return new ICmpInst(ICmpInst::ICMP_SLT, X, Zero);
}

if (match(Src, m_OneUse(m_c_Or(m_LShr(m_Value(X), m_ImmConstant(C)),
m_Deferred(X))))) {
// trunc (or (lshr X, C), X) to i1 --> icmp ne (and X, C'), 0
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/Transforms/InstCombine/2025-06-12-trunc-lshr.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=instcombine < %s | FileCheck %s

define i1 @src(i32 %0, ptr writeonly captures(none) initializes((0, 4)) %p) local_unnamed_addr #0 {
; CHECK-LABEL: define i1 @src(
; CHECK-SAME: i32 [[TMP0:%.*]], ptr writeonly captures(none) initializes((0, 4)) [[P:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[COMMON_RET1:.*:]]
; CHECK-NEXT: [[DOTLOBIT:%.*]] = lshr i32 [[TMP0]], 31
; CHECK-NEXT: store i32 [[DOTLOBIT]], ptr [[P]], align 1
; CHECK-NEXT: ret i1 false
;
common.ret1:
%.lobit = lshr i32 %0, 31
%1 = trunc nuw i32 %.lobit to i1
%2 = icmp slt i32 %0, 0
%not. = xor i1 %1, true
%common.ret1.op = select i1 %not., i1 %2, i1 false
store i32 %.lobit, ptr %p, align 1
ret i1 %common.ret1.op
}

attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }

Loading