[llvm] ffdbd2a - [Attributor] Look through (some) casts in AAValueConstantRangeFloating

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 9 22:38:46 PST 2020


Author: Johannes Doerfert
Date: 2020-02-10T00:38:01-06:00
New Revision: ffdbd2a06ca2a2703647fb87140b8965b3b0218c

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

LOG: [Attributor] Look through (some) casts in AAValueConstantRangeFloating

Casts can be handled natively by the ConstantRange class. We do limit it
to extends for now as we assume an integer type in different locations.
A TODO and a test case with a FIXME was added to remove that restriction
in the future.

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/Attributor.cpp
    llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
    llvm/test/Transforms/Attributor/range.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 8b97e3d6b1a7..f16b9bc29719 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -6183,6 +6183,12 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
         return;
       }
 
+    // We handle casts in the updateImpl.
+    // TODO: Allow non integers as well.
+    if (CastInst *CI = dyn_cast<CastInst>(&V))
+      if (CI->getOperand(0)->getType()->isIntegerTy())
+        return;
+
     // Otherwise we give up.
     indicatePessimisticFixpoint();
 
@@ -6212,6 +6218,20 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
     return T.isValidState();
   }
 
+  bool calculateCastInst(Attributor &A, CastInst *CastI, IntegerRangeState &T,
+                         Instruction *CtxI) {
+    assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
+    // TODO: Allow non integers as well.
+    Value &OpV = *CastI->getOperand(0);
+    assert(OpV.getType()->isIntegerTy() && "Expected integer cast");
+
+    auto &OpAA =
+        A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
+    T.unionAssumed(
+        OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
+    return T.isValidState();
+  }
+
   bool calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
                         Instruction *CtxI) {
     Value *LHS = CmpI->getOperand(0);
@@ -6282,6 +6302,8 @@ struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
         return calculateBinaryOperator(A, BinOp, T, CtxI);
       else if (auto *CmpI = dyn_cast<CmpInst>(I))
         return calculateCmpInst(A, CmpI, T, CtxI);
+      else if (auto *CastI = dyn_cast<CastInst>(I))
+        return calculateCastInst(A, CastI, T, CtxI);
       else {
         // Give up with other instructions.
         // TODO: Add other instructions

diff  --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
index d1fed5af151c..c3fe2b4fcfea 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
@@ -4,12 +4,13 @@
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
+; FIXME: Use the undef and do not pessimise the result because of it (no !range)
 define i64 @fn2() {
 ; CHECK-LABEL: define {{[^@]+}}@fn2()
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[CONV:%.*]] = sext i32 undef to i64
 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 8, [[CONV]]
-; CHECK-NEXT:    [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #{{[0-9]+}}, !range !0
+; CHECK-NEXT:    [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0
 ; CHECK-NEXT:    ret i64 [[CALL2]]
 ;
 entry:
@@ -19,6 +20,22 @@ entry:
   ret i64 %call2
 }
 
+define i64 @fn2b(i32 %arg) {
+; CHECK-LABEL: define {{[^@]+}}@fn2b
+; CHECK-SAME: (i32 [[ARG:%.*]])
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[CONV:%.*]] = sext i32 [[ARG]] to i64
+; CHECK-NEXT:    [[DIV:%.*]] = sdiv i64 8, [[CONV]]
+; CHECK-NEXT:    [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0
+; CHECK-NEXT:    ret i64 [[CALL2]]
+;
+entry:
+  %conv = sext i32 %arg to i64
+  %div = sdiv i64 8, %conv
+  %call2 = call i64 @fn1(i64 %div)
+  ret i64 %call2
+}
+
 define internal i64 @fn1(i64 %p1) {
 ; CHECK-LABEL: define {{[^@]+}}@fn1
 ; CHECK-SAME: (i64 returned [[P1:%.*]])

diff  --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index 76ae68885daa..0bdf83e46f30 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -665,9 +665,38 @@ entry:
   ret i1 %cmp6
 }
 
-; FIXME: We do not look through the zext here.
 define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@select_zext
+; OLD_PM-LABEL: define {{[^@]+}}@select_zext
+; OLD_PM-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; OLD_PM-NEXT:  entry:
+; OLD_PM-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
+; OLD_PM-NEXT:    [[DOT:%.*]] = select i1 [[CMP]], i32 1, i32 2
+; OLD_PM-NEXT:    [[CMP1:%.*]] = icmp sgt i32 [[A]], 10
+; OLD_PM-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
+; OLD_PM-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
+; OLD_PM-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
+; OLD_PM-NEXT:    [[DOT13:%.*]] = zext i1 [[CMP6]] to i32
+; OLD_PM-NEXT:    ret i32 [[DOT13]]
+;
+; NEW_PM-LABEL: define {{[^@]+}}@select_zext
+; NEW_PM-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; NEW_PM-NEXT:  entry:
+; NEW_PM-NEXT:    ret i32 0
+;
+entry:
+  %cmp = icmp sgt i32 %a, 5
+  %. = select i1 %cmp, i32 1, i32 2
+  %cmp1 = icmp sgt i32 %a, 10
+  %y.0.v = select i1 %cmp1, i32 1, i32 2
+  %y.0 = add nuw nsw i32 %., %y.0.v
+  %cmp6 = icmp eq i32 %y.0, 5
+  %.13 = zext i1 %cmp6 to i32
+  ret i32 %.13
+}
+
+; FIXME: We do not look through the ptr casts here.
+define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {
+; CHECK-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
 ; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A]], 5
@@ -676,8 +705,10 @@ define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
 ; CHECK-NEXT:    [[Y_0_V:%.*]] = select i1 [[CMP1]], i32 1, i32 2
 ; CHECK-NEXT:    [[Y_0:%.*]] = add nuw nsw i32 [[DOT]], [[Y_0_V]]
 ; CHECK-NEXT:    [[CMP6:%.*]] = icmp eq i32 [[Y_0]], 5
-; CHECK-NEXT:    [[DOT13:%.*]] = zext i1 [[CMP6]] to i32
-; CHECK-NEXT:    ret i32 [[DOT13]]
+; CHECK-NEXT:    [[I2P:%.*]] = inttoptr i1 [[CMP6]] to i1*
+; CHECK-NEXT:    [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
+; CHECK-NEXT:    [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
+; CHECK-NEXT:    ret i64 [[P2I]]
 ;
 entry:
   %cmp = icmp sgt i32 %a, 5
@@ -686,8 +717,10 @@ entry:
   %y.0.v = select i1 %cmp1, i32 1, i32 2
   %y.0 = add nuw nsw i32 %., %y.0.v
   %cmp6 = icmp eq i32 %y.0, 5
-  %.13 = zext i1 %cmp6 to i32
-  ret i32 %.13
+  %i2p = inttoptr i1 %cmp6 to i1*
+  %bc = bitcast i1* %i2p to i32*
+  %p2i = ptrtoint i32* %bc to i64
+  ret i64 %p2i
 }
 
 ; }


        


More information about the llvm-commits mailing list