diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 8b4f315949912..c139850eb9963 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1786,8 +1786,17 @@ bool TargetLowering::SimplifyDemandedBits( APInt InDemandedMask = DemandedBits.lshr(ShAmt); if (SimplifyDemandedBits(Op0, InDemandedMask, DemandedElts, Known, TLO, - Depth + 1)) + Depth + 1)) { + SDNodeFlags Flags = Op.getNode()->getFlags(); + if (Flags.hasNoSignedWrap() || Flags.hasNoUnsignedWrap()) { + // Disable the nsw and nuw flags. We can no longer guarantee that we + // won't wrap after simplification. + Flags.setNoSignedWrap(false); + Flags.setNoUnsignedWrap(false); + Op->setFlags(Flags); + } return true; + } assert(!Known.hasConflict() && "Bits known to be one AND zero?"); Known.Zero <<= ShAmt; Known.One <<= ShAmt; diff --git a/llvm/test/CodeGen/X86/pr69965.ll b/llvm/test/CodeGen/X86/pr69965.ll index 47bec4d7b1ab5..33bea976c7896 100644 --- a/llvm/test/CodeGen/X86/pr69965.ll +++ b/llvm/test/CodeGen/X86/pr69965.ll @@ -10,10 +10,12 @@ define i64 @PR69965(ptr %input_ptrs, ptr %output_ptrs) { ; X86-NEXT: movl (%eax), %eax ; X86-NEXT: movzbl (%eax), %eax ; X86-NEXT: notl %eax -; X86-NEXT: movzbl %al, %edx -; X86-NEXT: shll $8, %eax +; X86-NEXT: movl %eax, %edx +; X86-NEXT: shll $8, %edx ; X86-NEXT: movl (%ecx), %ecx -; X86-NEXT: leal (%eax,%edx,2), %eax +; X86-NEXT: addb %al, %al +; X86-NEXT: movzbl %al, %eax +; X86-NEXT: orl %edx, %eax ; X86-NEXT: orl $32768, %eax # imm = 0x8000 ; X86-NEXT: movw %ax, (%ecx) ; X86-NEXT: xorl %eax, %eax @@ -25,13 +27,14 @@ define i64 @PR69965(ptr %input_ptrs, ptr %output_ptrs) { ; X64-NEXT: movq (%rdi), %rax ; X64-NEXT: movzbl (%rax), %eax ; X64-NEXT: notl %eax -; X64-NEXT: movzbl %al, %ecx -; X64-NEXT: # kill: def $eax killed $eax def $rax +; X64-NEXT: leal (%rax,%rax), %ecx +; X64-NEXT: # kill: def $eax killed $eax killed $rax ; X64-NEXT: shll $8, %eax ; X64-NEXT: movq (%rsi), %rdx -; X64-NEXT: leal (%rax,%rcx,2), %eax -; X64-NEXT: orl $32768, %eax # imm = 0x8000 -; X64-NEXT: movw %ax, (%rdx) +; X64-NEXT: movzbl %cl, %ecx +; X64-NEXT: orl %eax, %ecx +; X64-NEXT: orl $32768, %ecx # imm = 0x8000 +; X64-NEXT: movw %cx, (%rdx) ; X64-NEXT: xorl %eax, %eax ; X64-NEXT: retq entry: