[PATCH] D93850: [InstCombine] Rewrite (switch (zext X)) as (switch X).

Chenguang Wang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 27 22:21:14 PST 2020


wecing added a comment.

Here is a longer example showing the improvements of this change:

  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
  
  define i32 @f1({ i32, i32 }* %x, { i32, i32 }* %y) {
  start:
    %0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
    %1 = load i32, i32* %0, align 4, !range !5
    %_1 = zext i32 %1 to i64
    %2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
    %3 = load i32, i32* %2, align 4, !range !5
    %_3 = zext i32 %3 to i64
    %cond1 = icmp eq i64 %_1, %_3
    br i1 %cond1, label %bb1, label %bb41
  
  bb1:
    switch i64 %_1, label %bb41 [
      i64 0, label %bb2
      i64 1, label %bb5
      i64 2, label %bb7
      i64 3, label %bb9
    ]
  
  bb2:
    ret i32 100
  
  bb5:
    ret i32 101
  
  bb7:
    ret i32 102
  
  bb9:
    %4 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
    %5 = load i32, i32* %4, align 4, !range !5
    %_5 = zext i32 %5 to i64
    %cond2 = icmp eq i64 %_5, 3
    br i1 %cond2, label %bb10, label %bb11
  
  bb10:
    ret i32 1001
  
  bb11:
    ret i32 1002
  
  bb41:
    unreachable
  }
  
  !5 = !{i32 0, i32 4}

Without this patch, `opt -S -O3 no.ll` produces:

  define i32 @f1({ i32, i32 }* nocapture readonly %x, { i32, i32 }* nocapture readonly %y) local_unnamed_addr #0 {
  start:
    %0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
    %1 = load i32, i32* %0, align 4, !range !0
    %_1 = zext i32 %1 to i64
    %2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
    %3 = load i32, i32* %2, align 4, !range !0
    %cond1 = icmp eq i32 %1, %3
    tail call void @llvm.assume(i1 %cond1)
    switch i64 %_1, label %bb41 [
      i64 0, label %bb2
      i64 1, label %bb5
      i64 2, label %bb7
      i64 3, label %bb9
    ]
  
  bb2:                                              ; preds = %bb9, %bb7, %bb5, %start
    %merge = phi i32 [ 100, %start ], [ 101, %bb5 ], [ 102, %bb7 ], [ %., %bb9 ]
    ret i32 %merge
  
  bb5:                                              ; preds = %start
    br label %bb2
  
  bb7:                                              ; preds = %start
    br label %bb2
  
  bb9:                                              ; preds = %start
    %cond2 = icmp eq i32 %1, 3
    %. = select i1 %cond2, i32 1001, i32 1002
    br label %bb2
  
  bb41:                                             ; preds = %start
    unreachable
  }
  
  !0 = !{i32 0, i32 4}

Note that the `icmp eq i32 %1, 3` in `bb9` is actually is unnecessary, because in the input, `icmp eq i64 %_1, %_3` from the `start` block must be true.

With this fix, the output becomes:

  define i32 @f1({ i32, i32 }* nocapture readonly %x, { i32, i32 }* nocapture readonly %y) local_unnamed_addr #0 {
  start:
    %0 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %x, i64 0, i32 0
    %1 = load i32, i32* %0, align 4, !range !0
    %2 = getelementptr inbounds { i32, i32 }, { i32, i32 }* %y, i64 0, i32 0
    %3 = load i32, i32* %2, align 4, !range !0
    %cond1 = icmp eq i32 %1, %3
    tail call void @llvm.assume(i1 %cond1)
    switch i32 %1, label %bb41 [
      i32 0, label %bb2
      i32 1, label %bb5
      i32 2, label %bb7
      i32 3, label %bb9
    ]
  
  bb2:                                              ; preds = %bb9, %bb7, %bb5, %start
    %merge = phi i32 [ 100, %start ], [ 101, %bb5 ], [ 102, %bb7 ], [ 1001, %bb9 ]
    ret i32 %merge
  
  bb5:                                              ; preds = %start
    br label %bb2
  
  bb7:                                              ; preds = %start
    br label %bb2
  
  bb9:                                              ; preds = %start
    br label %bb2
  
  bb41:                                             ; preds = %start
    unreachable
  }
  
  !0 = !{i32 0, i32 4}

The difference is also reflected in output assembly.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D93850



More information about the llvm-commits mailing list