Skip to content

Commit 27e0a48

Browse files
committed
preserve nsw flag
1 parent 77d3461 commit 27e0a48

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1895,7 +1895,11 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
18951895
if (match(I0, m_OneUse(m_NUWShl(m_Value(Base), m_Value(Shamt1)))) &&
18961896
match(I1, m_OneUse(m_NUWShl(m_Deferred(Base), m_Value(Shamt2))))) {
18971897
Value *MaxMin = Builder.CreateBinaryIntrinsic(IID, Shamt1, Shamt2);
1898-
return BinaryOperator::CreateNUWShl(Base, MaxMin);
1898+
auto *NewShl = BinaryOperator::CreateNUWShl(Base, MaxMin);
1899+
if (cast<BinaryOperator>(I0)->hasNoSignedWrap() &&
1900+
cast<BinaryOperator>(I1)->hasNoSignedWrap())
1901+
NewShl->setHasNoSignedWrap();
1902+
return NewShl;
18991903
}
19001904

19011905
// If both operands of unsigned min/max are sign-extended, it is still ok

llvm/test/Transforms/InstCombine/shift-uminmax.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,8 @@ define i32 @test_umin_shl_no_nuw_flag(i32 %x, i32 %y) {
310310
define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) {
311311
; CHECK-LABEL: define i32 @test_umax_shl_preserve_nsw(
312312
; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
313-
; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]]
314-
; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]]
315-
; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SHL_X]], i32 [[SHL_Y]])
313+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y]])
314+
; CHECK-NEXT: [[MAX:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]]
316315
; CHECK-NEXT: ret i32 [[MAX]]
317316
;
318317
%shl_x = shl nuw nsw i32 %base, %x
@@ -324,9 +323,8 @@ define i32 @test_umax_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) {
324323
define i32 @test_umin_shl_preserve_nsw(i32 %base, i32 %x, i32 %y) {
325324
; CHECK-LABEL: define i32 @test_umin_shl_preserve_nsw(
326325
; CHECK-SAME: i32 [[BASE:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) {
327-
; CHECK-NEXT: [[SHL_X:%.*]] = shl nuw nsw i32 [[BASE]], [[X]]
328-
; CHECK-NEXT: [[SHL_Y:%.*]] = shl nuw nsw i32 [[BASE]], [[Y]]
329-
; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[SHL_X]], i32 [[SHL_Y]])
326+
; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y]])
327+
; CHECK-NEXT: [[MIN:%.*]] = shl nuw nsw i32 [[BASE]], [[TMP1]]
330328
; CHECK-NEXT: ret i32 [[MIN]]
331329
;
332330
%shl_x = shl nuw nsw i32 %base, %x

0 commit comments

Comments
 (0)