Bug type: miscompilation
Component: VectorCombine
Bug location: llvm/lib/Transforms/Vectorize/VectorCombine.cpp: VectorCombine::foldExtractedCmps
Issue title: [VectorCombine] miscompilation
Labels: miscompilation
Reported by: bongjunj

Alive2 report: https://alive2.llvm.org/ce/z/YwSTI4

```llvm
----------------------------------------
define i1 @icmp_xor_v4i32.2(<4 x i32> %a) {
#0:
  %e1 = extractelement <4 x i32> %a, i32 3
  %e2 = extractelement <4 x i32> %a, i32 1
  %cmp1 = icmp sgt i32 %e1, 42
  %cmp2 = icmp sgt i32 %e2, 4294967288
  %#1 = ashr i1 %cmp1, %cmp2
  ret i1 %#1
}
=>
define i1 @icmp_xor_v4i32.2(<4 x i32> %a) {
#0:
  %#1 = icmp sgt <4 x i32> %a, { poison, 4294967288, poison, 42 }
  %shift = shufflevector <4 x i1> %#1, <4 x i1> poison, 4294967295, 3, 4294967295, 4294967295
  %#2 = ashr <4 x i1> %#1, %shift
  %#3 = extractelement <4 x i1> %#2, i64 1
  ret i1 %#3
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
<4 x i32> %a = < #x00000000 (0), #xfffffff8 (4294967288, -8), #x00000000 (0), #x0000002b (43) >

Source:
i32 %e1 = #x0000002b (43)
i32 %e2 = #xfffffff8 (4294967288, -8)
i1 %cmp1 = #x1 (1)
i1 %cmp2 = #x0 (0)
i1 %#1 = #x1 (1)

Target:
<4 x i1> %#1 = < poison, #x0 (0), poison, #x1 (1) >
<4 x i1> %shift = < poison, #x1 (1), poison, poison >
<4 x i1> %#2 = < poison, poison, poison, poison >
i1 %#3 = poison
Source value: #x1 (1)
Target value: poison

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
```

Comments: author: RKSimon
body: It looks like the ashr operands have been commuted in the fold - will take a look later today

Fix patch:
commit 05e838f428555bcc4507bd37912da60ea9110ef6
Author: Simon Pilgrim <llvm-dev@redking.me.uk>
Date:   Tue Nov 5 11:42:20 2024 +0000

    [VectorCombine] foldExtractedCmps - disable fold on non-commutative binops
    
    The fold needs to be adjusted to correctly track the LHS/RHS operands, which will take some refactoring, for now just disable the fold in this case.
    
    Fixes #114901

diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 025234c54956..332c52040e21 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -1032,9 +1032,15 @@ bool VectorCombine::scalarizeBinopOrCmp(Instruction &I) {
 /// a vector into vector operations followed by extract. Note: The SLP pass
 /// may miss this pattern because of implementation problems.
 bool VectorCombine::foldExtractedCmps(Instruction &I) {
+  auto *BI = dyn_cast<BinaryOperator>(&I);
+
   // We are looking for a scalar binop of booleans.
   // binop i1 (cmp Pred I0, C0), (cmp Pred I1, C1)
-  if (!I.isBinaryOp() || !I.getType()->isIntegerTy(1))
+  if (!BI || !I.getType()->isIntegerTy(1))
+    return false;
+
+  // TODO: Support non-commutative binary ops.
+  if (!BI->isCommutative())
     return false;
 
   // The compare predicates should match, and each compare should have a
@@ -1113,8 +1119,7 @@ bool VectorCombine::foldExtractedCmps(Instruction &I) {
   Value *VCmp = Builder.CreateCmp(Pred, X, ConstantVector::get(CmpC));
 
   Value *Shuf = createShiftShuffle(VCmp, ExpensiveIndex, CheapIndex, Builder);
-  Value *VecLogic = Builder.CreateBinOp(cast<BinaryOperator>(I).getOpcode(),
-                                        VCmp, Shuf);
+  Value *VecLogic = Builder.CreateBinOp(BI->getOpcode(), VCmp, Shuf);
   Value *NewExt = Builder.CreateExtractElement(VecLogic, CheapIndex);
   replaceValue(I, *NewExt);
   ++NumVecCmpBO;


Regression tests:
file: llvm/test/Transforms/VectorCombine/X86/pr114901.ll
commands: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2
opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2
tests: test_name: PR114901
test_body: define i1 @PR114901(<4 x i32> %a) {
  %e1 = extractelement <4 x i32> %a, i32 1
  %e3 = extractelement <4 x i32> %a, i32 3
  %cmp1 = icmp sgt i32 %e1, -8
  %cmp3 = icmp sgt i32 %e3, 42
  %r = ashr i1 %cmp3, %cmp1
  ret i1 %r
}