Bug type: miscompilation
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp: InstCombinerImpl::SimplifyDemandedUseBits
Issue title: [clang] Miscompile with -O2/3/s
Labels: miscompilation
llvm:instcombine
regression:19
Reported by: cardigan1008

This code prints random value at `-O2/3/s` and -1 at `-O0/1`:

```c
int printf(const char *, ...);
int a, b;
void c(char d) { a = d; }
int e(int d) {
  if (d < 0)
    return 1;
  return 0;
}
int f() {
  if (b)
    return 0;
  return 1;
}
int g(int d) {
  int h = 0;
  if (3 + d)
    h = f() - 1 - 1;
  return e(h) + h + h;
}
int main() {
  int i = g(0);
  c(i);
  printf("%d\n", a);
}
```

Compiler Explorer: https://godbolt.org/z/KfWsKxcvE

It starts from x86_64 clang 19.1.0. 

Comments: author: MaskRay
body: InstCombine miscompiles 

```llvm
define i32 @src(i32 %x) local_unnamed_addr {
entry:
  %cmp = icmp eq i32 %x, 0
  %zext = zext i1 %cmp to i32
  %or = or disjoint i32 %zext, -2
  %fshl = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 %or, i32 %or, i32 1)
  %tr = trunc nsw i32 %fshl to i8
  %res = sext i8 %tr to i32
  ret i32 %res
}
```

edit: `g` has a Range return attribute, which is propagated to the call site in `main` after inlining.
InstCombine `InstCombinerImpl::SimplifyDemandedUseBits` simplifies the operand, but keeps the no-longer-valid Range return attribute.

Then, CorrelatedValuePropagationPass added nsw, and the value eventually becomes poison.
author: nikic
body: Slightly reduced: https://alive2.llvm.org/ce/z/3Kf7-2

I assume the problem is that we don't clear the return range attribute in SimplifyDemanded.

Fix patch:
commit 2131115be5b9d8b39af80973d9b64c0adc41d38d
Author: Fangrui Song <i@maskray.me>
Date:   Sat Jan 25 13:35:11 2025 -0800

    [InstCombine] Drop Range attribute when simplifying 'fshl' based on demanded bits (#124429)
    
    When simplifying operands based on demanded bits, the return value range
    of llvm.fshl might change. Keeping the Range attribute might cause
    llvm.fshl to generate a poison and lead to miscompile. Drop the Range
    attribute similar to `dropPosonGeneratingFlags` elsewhere.
    
    Fix #124387

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 943598a30f04..2c8939b5a051 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -1039,11 +1039,14 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Instruction *I,
         APInt DemandedMaskLHS(DemandedMask.lshr(ShiftAmt));
         APInt DemandedMaskRHS(DemandedMask.shl(BitWidth - ShiftAmt));
         if (I->getOperand(0) != I->getOperand(1)) {
-          if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown,
-                                   Depth + 1, Q) ||
+          if (SimplifyDemandedBits(I, 0, DemandedMaskLHS, LHSKnown, Depth + 1,
+                                   Q) ||
               SimplifyDemandedBits(I, 1, DemandedMaskRHS, RHSKnown, Depth + 1,
-                                   Q))
+                                   Q)) {
+            // Range attribute may no longer hold.
+            I->dropPoisonGeneratingReturnAttributes();
             return I;
+          }
         } else { // fshl is a rotate
           // Avoid converting rotate into funnel shift.
           // Only simplify if one operand is constant.


Regression tests:
file: llvm/test/Transforms/InstCombine/fsh.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: fshl_range_trunc
test_body: ; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare i32 @llvm.fshl.i32(i32, i32, i32) #0

define i8 @fshl_range_trunc(i1 %x) {
  %zext = zext i1 %x to i32
  %or = or disjoint i32 %zext, -2
  %fshl = call range(i32 -4, 2) i32 @llvm.fshl.i32(i32 %or, i32 %or, i32 1)
  %tr = trunc nsw i32 %fshl to i8
  ret i8 %tr
}

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }