llvm.org GIT mirror llvm / 4bbb5ef
[WideableCond] Fix a nasty bug in detection of "explicit guards" The code was failing to actually check for the presence of the call to widenable_condition. The whole point of specifying the widenable_condition intrinsic was allowing widening transforms. A normal branch is not widenable. A normal branch leading to a deopt is not widenable (in general). I added a test case via LoopPredication, but GuardWidening has an analogous bug. Those are the only two passes actually using this utility just yet. Noticed while working on LoopPredication for non-widenable branches; POC in D60111. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357493 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 5 months ago
2 changed file(s) with 66 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
3838 Value *&WidenableCondition,
3939 BasicBlock *&IfTrueBB, BasicBlock *&IfFalseBB) {
4040 using namespace llvm::PatternMatch;
41 return match(U, m_Br(m_And(m_Value(Condition), m_Value(WidenableCondition)),
42 IfTrueBB, IfFalseBB));
41 if (!match(U, m_Br(m_And(m_Value(Condition), m_Value(WidenableCondition)),
42 IfTrueBB, IfFalseBB)))
43 return false;
44 // TODO: At the moment, we only recognize the branch if the WC call in this
45 // specific position. We should generalize!
46 return match(WidenableCondition,
47 m_Intrinsic());
4348 }
18621862 ret i32 %result
18631863 }
18641864
1865 ; Make sure that if we're going to consider a branch widenable, that the
1866 ; call to widenable condition is actually present.
1867 define i32 @negative_WC_required(i32* %array, i32 %length, i32 %n, i1 %unrelated) {
1868 ; CHECK-LABEL: @negative_WC_required(
1869 ; CHECK-NEXT: entry:
1870 ; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[N:%.*]], 0
1871 ; CHECK-NEXT: br i1 [[TMP5]], label [[EXIT:%.*]], label [[LOOP_PREHEADER:%.*]]
1872 ; CHECK: loop.preheader:
1873 ; CHECK-NEXT: br label [[LOOP:%.*]]
1874 ; CHECK: loop:
1875 ; CHECK-NEXT: [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1876 ; CHECK-NEXT: [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
1877 ; CHECK-NEXT: [[NOT_WIDENABLE:%.*]] = and i1 [[WITHIN_BOUNDS]], [[UNRELATED:%.*]]
1878 ; CHECK-NEXT: br i1 [[NOT_WIDENABLE]], label [[GUARDED]], label [[DEOPT:%.*]], !prof !0
1879 ; CHECK: deopt:
1880 ; CHECK-NEXT: [[DEOPTCALL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1881 ; CHECK-NEXT: ret i32 [[DEOPTCALL]]
1882 ; CHECK: guarded:
1883 ; CHECK-NEXT: [[I_I64:%.*]] = zext i32 [[I]] to i64
1884 ; CHECK-NEXT: [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1885 ; CHECK-NEXT: store i32 0, i32* [[ARRAY_I_PTR]], align 4
1886 ; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
1887 ; CHECK-NEXT: [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1888 ; CHECK-NEXT: br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT_LOOPEXIT:%.*]]
1889 ; CHECK: exit.loopexit:
1890 ; CHECK-NEXT: br label [[EXIT]]
1891 ; CHECK: exit:
1892 ; CHECK-NEXT: ret i32 0
1893 ;
1894 entry:
1895 %tmp5 = icmp eq i32 %n, 0
1896 br i1 %tmp5, label %exit, label %loop.preheader
1897
1898 loop.preheader: ; preds = %entry
1899 br label %loop
1900
1901 loop:
1902 %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
1903 %within.bounds = icmp ult i32 %i, %length
1904 %not_widenable = and i1 %within.bounds, %unrelated
1905 br i1 %not_widenable, label %guarded, label %deopt, !prof !0
1906
1907 deopt:
1908 %deoptcall = call i32 (...) @llvm.experimental.deoptimize.i32(i32 9) [ "deopt"() ]
1909 ret i32 %deoptcall
1910
1911 guarded: ; preds = %loop
1912 %i.i64 = zext i32 %i to i64
1913 %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1914 store i32 0, i32* %array.i.ptr, align 4
1915 %i.next = add nuw i32 %i, 1
1916 %continue = icmp ult i32 %i.next, %n
1917 br i1 %continue, label %loop, label %exit
1918
1919 exit: ; preds = %guarded, %entry
1920 ret i32 0
1921 }
1922
1923
18651924 declare i32 @llvm.experimental.deoptimize.i32(...)
18661925
18671926 ; Function Attrs: inaccessiblememonly nounwind