Skip to content

Commit 0e13ce7

Browse files
authored
[InstCombine] Handle mul in maintainNoSignedWrap (#123299)
Alive2: https://alive2.llvm.org/ce/z/Kgamks Closes #123175. For `@foo1`, the nsw flag is propagated because we first convert it into `mul nsw nuw (shl nsw nuw X, 1), 3`.
1 parent 9720be9 commit 0e13ce7

File tree

2 files changed

+74
-9
lines changed

2 files changed

+74
-9
lines changed

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,28 +281,33 @@ bool InstCombinerImpl::shouldChangeType(Type *From, Type *To) const {
281281
// Return true, if No Signed Wrap should be maintained for I.
282282
// The No Signed Wrap flag can be kept if the operation "B (I.getOpcode) C",
283283
// where both B and C should be ConstantInts, results in a constant that does
284-
// not overflow. This function only handles the Add and Sub opcodes. For
284+
// not overflow. This function only handles the Add/Sub/Mul opcodes. For
285285
// all other opcodes, the function conservatively returns false.
286286
static bool maintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
287287
auto *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
288288
if (!OBO || !OBO->hasNoSignedWrap())
289289
return false;
290290

291-
// We reason about Add and Sub Only.
292-
Instruction::BinaryOps Opcode = I.getOpcode();
293-
if (Opcode != Instruction::Add && Opcode != Instruction::Sub)
294-
return false;
295-
296291
const APInt *BVal, *CVal;
297292
if (!match(B, m_APInt(BVal)) || !match(C, m_APInt(CVal)))
298293
return false;
299294

295+
// We reason about Add/Sub/Mul Only.
300296
bool Overflow = false;
301-
if (Opcode == Instruction::Add)
297+
switch (I.getOpcode()) {
298+
case Instruction::Add:
302299
(void)BVal->sadd_ov(*CVal, Overflow);
303-
else
300+
break;
301+
case Instruction::Sub:
304302
(void)BVal->ssub_ov(*CVal, Overflow);
305-
303+
break;
304+
case Instruction::Mul:
305+
(void)BVal->smul_ov(*CVal, Overflow);
306+
break;
307+
default:
308+
// Conservatively return false for other opcodes.
309+
return false;
310+
}
306311
return !Overflow;
307312
}
308313

llvm/test/Transforms/InstCombine/nsw.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,63 @@ define i8 @neg_nsw_mul_missing_nsw_on_mul(i8 %a1, i8 %a2, i8 %b) {
415415
%neg = sub nsw i8 0, %shl
416416
ret i8 %neg
417417
}
418+
419+
; This could propagate nsw.
420+
421+
define i16 @mul_nsw_reassoc_prop(i16 %x) {
422+
; CHECK-LABEL: @mul_nsw_reassoc_prop(
423+
; CHECK-NEXT: [[B:%.*]] = mul nsw i16 [[X:%.*]], 6
424+
; CHECK-NEXT: ret i16 [[B]]
425+
;
426+
%a = mul nsw i16 %x, 3
427+
%b = mul nsw i16 %a, 2
428+
ret i16 %b
429+
}
430+
431+
; This could propagate nsw.
432+
433+
define i16 @mul_nsw_reassoc_prop_neg(i16 %x) {
434+
; CHECK-LABEL: @mul_nsw_reassoc_prop_neg(
435+
; CHECK-NEXT: [[B:%.*]] = mul nsw i16 [[X:%.*]], -2201
436+
; CHECK-NEXT: ret i16 [[B]]
437+
;
438+
%a = mul nsw i16 %x, -71
439+
%b = mul nsw i16 %a, 31
440+
ret i16 %b
441+
}
442+
443+
; Must not propagate nsw.
444+
445+
define i16 @mul_nsw_reassoc_prop_no_nsw1(i16 %x) {
446+
; CHECK-LABEL: @mul_nsw_reassoc_prop_no_nsw1(
447+
; CHECK-NEXT: [[B:%.*]] = mul i16 [[X:%.*]], 6
448+
; CHECK-NEXT: ret i16 [[B]]
449+
;
450+
%a = mul i16 %x, 3
451+
%b = mul nsw i16 %a, 2
452+
ret i16 %b
453+
}
454+
455+
; Must not propagate nsw.
456+
457+
define i16 @mul_nsw_reassoc_prop_no_nsw2(i16 %x) {
458+
; CHECK-LABEL: @mul_nsw_reassoc_prop_no_nsw2(
459+
; CHECK-NEXT: [[B:%.*]] = mul i16 [[X:%.*]], 6
460+
; CHECK-NEXT: ret i16 [[B]]
461+
;
462+
%a = mul nsw i16 %x, 3
463+
%b = mul i16 %a, 2
464+
ret i16 %b
465+
}
466+
467+
; Must not propagate nsw.
468+
469+
define i16 @mul_nsw_reassoc_prop_overflow(i16 %x) {
470+
; CHECK-LABEL: @mul_nsw_reassoc_prop_overflow(
471+
; CHECK-NEXT: [[B:%.*]] = mul i16 [[X:%.*]], -31777
472+
; CHECK-NEXT: ret i16 [[B]]
473+
;
474+
%a = mul nsw i16 %x, 1023
475+
%b = mul nsw i16 %a, 33
476+
ret i16 %b
477+
}

0 commit comments

Comments
 (0)