[PATCH] D83360: [InstSimplify] Remove select ?, undef, X -> X and select ?, X, undef -> X

Vitaly Buka via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 10 22:12:55 PDT 2020


vitalybuka added subscribers: eugenis, guiand, vitalybuka.
vitalybuka added a comment.

After this patch we have false msan reports on code like this:

  bool iv_compare2(const int *op1, const int *op2) {
    if (op1[1] != op2[1]) return op1[1] < op2[1];
    for (int i = 1; i >= 0; i--) {
      if (op1[i] != op2[i]) return op1[i] < op2[i];
    }
    return false;
  }
  
  void foo() {
    int a[2] = {};
    int b[2] = {};
    auto UNINITIALIZED= iv_compare2(a, b);
  }

Here it looks fine and the same as before the patch. It returns "and undef, false" which should be false.

  *** IR Dump After Simplify the CFG ***
  ; Function Attrs: norecurse nounwind readonly sanitize_memory uwtable
  define zeroext i1 @_Z11iv_compare2PKiS0_(i32* nocapture readonly %op1, i32* nocapture readonly %op2) local_unnamed_addr #0 !dbg !8 {
  entry:
    %arrayidx = getelementptr inbounds i32, i32* %op1, i64 1, !dbg !10
    %0 = load i32, i32* %arrayidx, align 4, !dbg !10
    %arrayidx1 = getelementptr inbounds i32, i32* %op2, i64 1, !dbg !11
    %1 = load i32, i32* %arrayidx1, align 4, !dbg !11
    %cmp.not = icmp eq i32 %0, %1, !dbg !12
    br i1 %cmp.not, label %for.cond, label %if.then, !dbg !10
  
  if.then:                                          ; preds = %entry
    %cmp4 = icmp slt i32 %0, %1, !dbg !13
    ret i1 %cmp4, !dbg !14
  
  for.cond:                                         ; preds = %entry
    %2 = load i32, i32* %op1, align 4, !dbg !15
    %3 = load i32, i32* %op2, align 4, !dbg !16
    %cmp9.not.1 = icmp eq i32 %2, %3, !dbg !17
    %cmp15 = icmp slt i32 %2, %3
    %spec.select39 = select i1 %cmp9.not.1, i1 undef, i1 %cmp15, !dbg !15
    %spec.select40 = select i1 %cmp9.not.1, i1 false, i1 true, !dbg !15
    %spec.select = and i1 %spec.select39, %spec.select40
    ret i1 %spec.select
  }

However with this patch after the next transformation it breaks the code:
Now it returns undef instead of false if %2 == %3

  *** IR Dump After Combine redundant instructions ***
  ; Function Attrs: norecurse nounwind readonly sanitize_memory uwtable
  define zeroext i1 @_Z11iv_compare2PKiS0_(i32* nocapture readonly %op1, i32* nocapture readonly %op2) local_unnamed_addr #0 !dbg !8 {
  entry:
    %arrayidx = getelementptr inbounds i32, i32* %op1, i64 1, !dbg !10
    %0 = load i32, i32* %arrayidx, align 4, !dbg !10
    %arrayidx1 = getelementptr inbounds i32, i32* %op2, i64 1, !dbg !11
    %1 = load i32, i32* %arrayidx1, align 4, !dbg !11
    %cmp.not = icmp eq i32 %0, %1, !dbg !12
    br i1 %cmp.not, label %for.cond, label %if.then, !dbg !10
  
  if.then:                                          ; preds = %entry
    %cmp4 = icmp slt i32 %0, %1, !dbg !13
    ret i1 %cmp4, !dbg !14
  
  for.cond:                                         ; preds = %entry
    %2 = load i32, i32* %op1, align 4, !dbg !15
    %3 = load i32, i32* %op2, align 4, !dbg !16
    %cmp9.not.1 = icmp eq i32 %2, %3, !dbg !17
    %cmp15 = icmp slt i32 %2, %3
    %spec.select39 = select i1 %cmp9.not.1, i1 undef, i1 %cmp15, !dbg !15
    ret i1 %spec.select39
  }

The msan reasonably reports a bug.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83360/new/

https://reviews.llvm.org/D83360





More information about the cfe-commits mailing list