[llvm] c771087 - [InstCombine] Fold freeze(undef) into a proper constant

Juneyoung Lee via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 6 02:40:32 PDT 2020


Author: Juneyoung Lee
Date: 2020-08-06T18:40:04+09:00
New Revision: c771087161f4948a4d56d64e433f6bbc9dbfad90

URL: https://github.com/llvm/llvm-project/commit/c771087161f4948a4d56d64e433f6bbc9dbfad90
DIFF: https://github.com/llvm/llvm-project/commit/c771087161f4948a4d56d64e433f6bbc9dbfad90.diff

LOG: [InstCombine] Fold freeze(undef) into a proper constant

This is a simple patch that folds freeze(undef) into a proper constant after inspecting its uses.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D84948

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
    llvm/test/Transforms/InstCombine/freeze-phi.ll
    llvm/test/Transforms/InstCombine/freeze.ll
    llvm/test/Transforms/InstCombine/select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index ceeddda05fd9..be86c1f111a3 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3387,6 +3387,34 @@ Instruction *InstCombinerImpl::visitFreeze(FreezeInst &I) {
       return NV;
   }
 
+  if (match(Op0, m_Undef())) {
+    // If I is freeze(undef), see its uses and fold it to the best constant.
+    // - or: pick -1
+    // - select's condition: pick the value that leads to choosing a constant
+    // - other ops: pick 0
+    Constant *BestValue = nullptr;
+    Constant *NullValue = Constant::getNullValue(I.getType());
+    for (const auto *U : I.users()) {
+      Constant *C = NullValue;
+
+      if (match(U, m_Or(m_Value(), m_Value())))
+        C = Constant::getAllOnesValue(I.getType());
+      else if (const auto *SI = dyn_cast<SelectInst>(U)) {
+        if (SI->getCondition() == &I) {
+          APInt CondVal(1, isa<Constant>(SI->getFalseValue()) ? 0 : 1);
+          C = Constant::getIntegerValue(I.getType(), CondVal);
+        }
+      }
+
+      if (!BestValue)
+        BestValue = C;
+      else if (BestValue != C)
+        BestValue = NullValue;
+    }
+
+    return replaceInstUsesWith(I, BestValue);
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/freeze-phi.ll b/llvm/test/Transforms/InstCombine/freeze-phi.ll
index b8dde691a11c..a00ea6fde51d 100644
--- a/llvm/test/Transforms/InstCombine/freeze-phi.ll
+++ b/llvm/test/Transforms/InstCombine/freeze-phi.ll
@@ -154,14 +154,13 @@ define i32 @one_undef(i8 %cond) {
 ; CHECK-NEXT:    i8 1, label [[C:%.*]]
 ; CHECK-NEXT:    ]
 ; CHECK:       A:
-; CHECK-NEXT:    [[PHI_FR:%.*]] = freeze i32 undef
 ; CHECK-NEXT:    br label [[D:%.*]]
 ; CHECK:       B:
 ; CHECK-NEXT:    br label [[D]]
 ; CHECK:       C:
 ; CHECK-NEXT:    br label [[D]]
 ; CHECK:       D:
-; CHECK-NEXT:    [[Y:%.*]] = phi i32 [ [[PHI_FR]], [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
+; CHECK-NEXT:    [[Y:%.*]] = phi i32 [ 0, [[A]] ], [ 32, [[B]] ], [ 0, [[C]] ]
 ; CHECK-NEXT:    ret i32 [[Y]]
 ;
   switch i8 %cond, label %A [

diff  --git a/llvm/test/Transforms/InstCombine/freeze.ll b/llvm/test/Transforms/InstCombine/freeze.ll
index d8c9a6bd105f..1a1ec2e2024d 100644
--- a/llvm/test/Transforms/InstCombine/freeze.ll
+++ b/llvm/test/Transforms/InstCombine/freeze.ll
@@ -21,9 +21,7 @@ define i32 @make_const() {
 
 define i32 @and_freeze_undef(i32 %x) {
 ; CHECK-LABEL: @and_freeze_undef(
-; CHECK-NEXT:    [[F:%.*]] = freeze i32 undef
-; CHECK-NEXT:    [[RES:%.*]] = and i32 [[F]], [[X:%.*]]
-; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK-NEXT:    ret i32 0
 ;
   %f = freeze i32 undef
   %res = and i32 %x, %f
@@ -34,10 +32,8 @@ declare void @use_i32(i32)
 
 define i32 @and_freeze_undef_multipleuses(i32 %x) {
 ; CHECK-LABEL: @and_freeze_undef_multipleuses(
-; CHECK-NEXT:    [[F:%.*]] = freeze i32 undef
-; CHECK-NEXT:    [[RES:%.*]] = and i32 [[F]], [[X:%.*]]
-; CHECK-NEXT:    call void @use_i32(i32 [[F]])
-; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK-NEXT:    call void @use_i32(i32 0)
+; CHECK-NEXT:    ret i32 0
 ;
   %f = freeze i32 undef
   %res = and i32 %x, %f
@@ -47,9 +43,7 @@ define i32 @and_freeze_undef_multipleuses(i32 %x) {
 
 define i32 @or_freeze_undef(i32 %x) {
 ; CHECK-LABEL: @or_freeze_undef(
-; CHECK-NEXT:    [[F:%.*]] = freeze i32 undef
-; CHECK-NEXT:    [[RES:%.*]] = or i32 [[F]], [[X:%.*]]
-; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK-NEXT:    ret i32 -1
 ;
   %f = freeze i32 undef
   %res = or i32 %x, %f
@@ -58,10 +52,8 @@ define i32 @or_freeze_undef(i32 %x) {
 
 define i32 @or_freeze_undef_multipleuses(i32 %x) {
 ; CHECK-LABEL: @or_freeze_undef_multipleuses(
-; CHECK-NEXT:    [[F:%.*]] = freeze i32 undef
-; CHECK-NEXT:    [[RES:%.*]] = or i32 [[F]], [[X:%.*]]
-; CHECK-NEXT:    call void @use_i32(i32 [[F]])
-; CHECK-NEXT:    ret i32 [[RES]]
+; CHECK-NEXT:    call void @use_i32(i32 0)
+; CHECK-NEXT:    ret i32 [[X:%.*]]
 ;
   %f = freeze i32 undef
   %res = or i32 %x, %f
@@ -73,10 +65,7 @@ declare void @use_i32_i1(i32, i1)
 
 define void @or_select_multipleuses(i32 %x, i1 %y) {
 ; CHECK-LABEL: @or_select_multipleuses(
-; CHECK-NEXT:    [[F:%.*]] = freeze i1 undef
-; CHECK-NEXT:    [[A:%.*]] = select i1 [[F]], i32 [[X:%.*]], i32 32
-; CHECK-NEXT:    [[B:%.*]] = or i1 [[F]], [[Y:%.*]]
-; CHECK-NEXT:    call void @use_i32_i1(i32 [[A]], i1 [[B]])
+; CHECK-NEXT:    call void @use_i32_i1(i32 32, i1 [[Y:%.*]])
 ; CHECK-NEXT:    ret void
 ;
   %f = freeze i1 undef

diff  --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll
index 6233489e6fda..ae21c5864e5b 100644
--- a/llvm/test/Transforms/InstCombine/select.ll
+++ b/llvm/test/Transforms/InstCombine/select.ll
@@ -2490,9 +2490,7 @@ define <2 x i32> @true_undef_vec(i1 %cond, <2 x i32> %x) {
 
 define i8 @cond_freeze(i8 %x, i8 %y) {
 ; CHECK-LABEL: @cond_freeze(
-; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 undef
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND_FR]], i8 [[X:%.*]], i8 [[Y:%.*]]
-; CHECK-NEXT:    ret i8 [[S]]
+; CHECK-NEXT:    ret i8 [[X:%.*]]
 ;
   %cond.fr = freeze i1 undef
   %s = select i1 %cond.fr, i8 %x, i8 %y
@@ -2501,9 +2499,7 @@ define i8 @cond_freeze(i8 %x, i8 %y) {
 
 define i8 @cond_freeze2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @cond_freeze2(
-; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 undef
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND_FR]], i8 [[X:%.*]], i8 1
-; CHECK-NEXT:    ret i8 [[S]]
+; CHECK-NEXT:    ret i8 1
 ;
   %cond.fr = freeze i1 undef
   %s = select i1 %cond.fr, i8 %x, i8 1
@@ -2512,9 +2508,7 @@ define i8 @cond_freeze2(i8 %x, i8 %y) {
 
 define i8 @cond_freeze3(i8 %x) {
 ; CHECK-LABEL: @cond_freeze3(
-; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 undef
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND_FR]], i8 1, i8 [[X:%.*]]
-; CHECK-NEXT:    ret i8 [[S]]
+; CHECK-NEXT:    ret i8 1
 ;
   %cond.fr = freeze i1 undef
   %s = select i1 %cond.fr, i8 1, i8 %x
@@ -2523,9 +2517,7 @@ define i8 @cond_freeze3(i8 %x) {
 
 define <2 x i8> @cond_freeze_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @cond_freeze_vec(
-; CHECK-NEXT:    [[COND_FR:%.*]] = freeze <2 x i1> undef
-; CHECK-NEXT:    [[S:%.*]] = select <2 x i1> [[COND_FR]], <2 x i8> <i8 1, i8 2>, <2 x i8> [[X:%.*]]
-; CHECK-NEXT:    ret <2 x i8> [[S]]
+; CHECK-NEXT:    ret <2 x i8> <i8 1, i8 2>
 ;
   %cond.fr = freeze <2 x i1> <i1 undef, i1 undef>
   %s = select <2 x i1> %cond.fr, <2 x i8> <i8 1, i8 2>, <2 x i8> %x
@@ -2536,10 +2528,7 @@ declare void @foo2(i8, i8)
 
 define void @cond_freeze_multipleuses(i8 %x, i8 %y) {
 ; CHECK-LABEL: @cond_freeze_multipleuses(
-; CHECK-NEXT:    [[COND_FR:%.*]] = freeze i1 undef
-; CHECK-NEXT:    [[S:%.*]] = select i1 [[COND_FR]], i8 [[X:%.*]], i8 [[Y:%.*]]
-; CHECK-NEXT:    [[S2:%.*]] = select i1 [[COND_FR]], i8 [[Y]], i8 [[X]]
-; CHECK-NEXT:    call void @foo2(i8 [[S]], i8 [[S2]])
+; CHECK-NEXT:    call void @foo2(i8 [[X:%.*]], i8 [[Y:%.*]])
 ; CHECK-NEXT:    ret void
 ;
   %cond.fr = freeze i1 undef


        


More information about the llvm-commits mailing list