[llvm] bfe05b1 - [Attributor][FIX] Do not attach range metadata to the wrong Instruction

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 27 20:08:41 PDT 2020


Author: Johannes Doerfert
Date: 2020-10-27T22:07:55-05:00
New Revision: bfe05b1aff1b8e5dd625f905879d7425c8460989

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

LOG: [Attributor][FIX] Do not attach range metadata to the wrong Instruction

If we are looking at a call site argument it might be a load or call
which is in a different context than the call site argument. We cannot
simply use the call site argument range for the call or load.

Bug reported and reduced by Whitney Tsang <whitneyt at ca.ibm.com>.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
index 1d516a71aba8..bdaad78cfe5e 100644
--- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
+++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp
@@ -7069,10 +7069,13 @@ struct AAValueConstantRangeImpl : AAValueConstantRange {
     auto &V = getAssociatedValue();
     if (!AssumedConstantRange.isEmptySet() &&
         !AssumedConstantRange.isSingleElement()) {
-      if (Instruction *I = dyn_cast<Instruction>(&V))
+      if (Instruction *I = dyn_cast<Instruction>(&V)) {
+        assert(I == getCtxI() && "Should not annotate an instruction which is "
+                                 "not the context instruction");
         if (isa<CallInst>(I) || isa<LoadInst>(I))
           if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
             Changed = ChangeStatus::CHANGED;
+      }
     }
 
     return Changed;
@@ -7381,6 +7384,11 @@ struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
   AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A)
       : AAValueConstantRangeFloating(IRP, A) {}
 
+  /// See AbstractAttribute::manifest()
+  ChangeStatus manifest(Attributor &A) override {
+    return ChangeStatus::UNCHANGED;
+  }
+
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override {
     STATS_DECLTRACK_CSARG_ATTR(value_range)

diff  --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index bbdf0ed9918c..a1ca947954f9 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -1876,6 +1876,154 @@ define i1 @propagate_range2(i32 %c) {
   ret i1 %true
 }
 
+define internal i1 @non_zero(i8 %v) {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@non_zero
+; IS__TUNIT_OPM-SAME: (i8 [[V:%.*]]) [[ATTR2]] {
+; IS__TUNIT_OPM-NEXT:    [[R:%.*]] = icmp ne i8 [[V]], 0
+; IS__TUNIT_OPM-NEXT:    ret i1 [[R]]
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@non_zero
+; IS__CGSCC_OPM-SAME: (i8 [[V:%.*]]) [[ATTR2]] {
+; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = icmp ne i8 [[V]], 0
+; IS__CGSCC_OPM-NEXT:    ret i1 [[R]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@non_zero
+; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
+; IS__CGSCC_NPM-NEXT:    ret i1 undef
+;
+  %r = icmp ne i8 %v, 0
+  ret i1 %r
+}
+
+; Avoid range metadata for %l below
+define i1 @context(i8* %p) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@context
+; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull readonly dereferenceable(1) [[P:%.*]]) [[ATTR0]] {
+; IS__TUNIT_OPM-NEXT:    [[L:%.*]] = load i8, i8* [[P]], align 1
+; IS__TUNIT_OPM-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
+; IS__TUNIT_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT_OPM:       t:
+; IS__TUNIT_OPM-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR2]]
+; IS__TUNIT_OPM-NEXT:    ret i1 [[R]]
+; IS__TUNIT_OPM:       f:
+; IS__TUNIT_OPM-NEXT:    ret i1 false
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@context
+; IS__TUNIT_NPM-SAME: (i8* nocapture nofree nonnull readonly dereferenceable(1) [[P:%.*]]) [[ATTR0]] {
+; IS__TUNIT_NPM-NEXT:    [[L:%.*]] = load i8, i8* [[P]], align 1
+; IS__TUNIT_NPM-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
+; IS__TUNIT_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT_NPM:       t:
+; IS__TUNIT_NPM-NEXT:    ret i1 true
+; IS__TUNIT_NPM:       f:
+; IS__TUNIT_NPM-NEXT:    ret i1 false
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@context
+; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readonly dereferenceable(1) [[P:%.*]]) [[ATTR0]] {
+; IS__CGSCC_OPM-NEXT:    [[L:%.*]] = load i8, i8* [[P]], align 1
+; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
+; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC_OPM:       t:
+; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR4]]
+; IS__CGSCC_OPM-NEXT:    ret i1 [[R]]
+; IS__CGSCC_OPM:       f:
+; IS__CGSCC_OPM-NEXT:    ret i1 false
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@context
+; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull readonly dereferenceable(1) [[P:%.*]]) [[ATTR0]] {
+; IS__CGSCC_NPM-NEXT:    [[L:%.*]] = load i8, i8* [[P]], align 1
+; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
+; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC_NPM:       t:
+; IS__CGSCC_NPM-NEXT:    ret i1 true
+; IS__CGSCC_NPM:       f:
+; IS__CGSCC_NPM-NEXT:    ret i1 false
+;
+  %l = load i8, i8* %p
+  %c = icmp slt i8 0, %l
+  br i1 %c, label %t, label %f
+t:
+  %r = call i1 @non_zero(i8 %l)
+  ret i1 %r
+f:
+  ret i1 false
+}
+
+
+define void @spam(i32* %arg, i32* %arg1) {
+; CHECK-LABEL: define {{[^@]+}}@spam
+; CHECK-SAME: (i32* nocapture nonnull readonly align 8 dereferenceable(4) [[ARG:%.*]], i32* nocapture nofree readnone [[ARG1:%.*]]) {
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[ARG]], align 8
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP]], 4
+; CHECK-NEXT:    br i1 [[TMP2]], label [[BB3:%.*]], label [[BB4:%.*]]
+; CHECK:       bb3:
+; CHECK-NEXT:    call fastcc void @wobble(i32 signext [[TMP]])
+; CHECK-NEXT:    br label [[BB5:%.*]]
+; CHECK:       bb4:
+; CHECK-NEXT:    call void @ham(i32 [[TMP]])
+; CHECK-NEXT:    br label [[BB5]]
+; CHECK:       bb5:
+; CHECK-NEXT:    ret void
+;
+bb:
+  %tmp = load i32, i32* %arg, align 8
+  %tmp2 = icmp ult i32 %tmp, 4
+  br i1 %tmp2, label %bb3, label %bb4
+
+bb3:                                              ; preds = %bb
+  call fastcc void @wobble(i32 signext %tmp)
+  br label %bb5
+
+bb4:                                              ; preds = %bb
+  call void @ham(i32 %tmp)
+  br label %bb5
+
+bb5:                                              ; preds = %bb4, %bb3
+  ret void
+}
+
+define internal fastcc void @wobble(i32 signext %arg) {
+; CHECK-LABEL: define {{[^@]+}}@wobble
+; CHECK-SAME: (i32 signext [[ARG:%.*]]) {
+; CHECK-NEXT:  bb:
+; CHECK-NEXT:    [[TMP:%.*]] = icmp ult i32 [[ARG]], 2
+; CHECK-NEXT:    br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    call void @barney(i32 noundef signext 32, i32 noundef signext 0)
+; CHECK-NEXT:    br label [[BB3:%.*]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[BB3]]
+; CHECK:       bb3:
+; CHECK-NEXT:    ret void
+;
+bb:
+  %tmp = icmp ult i32 %arg, 2
+  br i1 %tmp, label %bb1, label %bb2
+
+bb1:                                              ; preds = %bb
+  call void @barney(i32 signext 32, i32 signext 0)
+  br label %bb3
+
+bb2:                                              ; preds = %bb
+  br label %bb3
+
+bb3:                                              ; preds = %bb2, %bb1
+  ret void
+}
+
+declare void @ham(i32)
+
+declare void @barney(i32 signext, i32 signext)
+
+
 !0 = !{i32 0, i32 10}
 !1 = !{i32 10, i32 100}
 


        


More information about the llvm-commits mailing list