[llvm] [InstCombine] Fix buggy transform in foldNestedSelects; PR 71330 (PR #71489)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 8 06:10:19 PST 2023


================
@@ -0,0 +1,230 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt -passes=instcombine -S < %s | FileCheck %s
+
+ at b = global i16 0
+ at c = global i64 0
+ at k = global i8 0
+ at n = global i16 0
+ at a = global i8 0
+ at g = global i8 0
+
+define void @pr71330() {
+; CHECK-LABEL: define void @pr71330() {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_COND5_PREHEADER:%.*]]
+; CHECK:       for.cond5.preheader:
+; CHECK-NEXT:    [[LE2:%.*]] = load i8, ptr @g, align 1
+; CHECK-NEXT:    [[LE2_FR:%.*]] = freeze i8 [[LE2]]
+; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[LE2_FR]] to i32
+; CHECK-NEXT:    [[TOBOOL19_NOT4:%.*]] = icmp eq i8 [[LE2_FR]], 0
+; CHECK-NEXT:    [[C_PROMOTED22:%.*]] = load i64, ptr @c, align 4
+; CHECK-NEXT:    [[NARROW:%.*]] = sub nsw i32 6, [[CONV]]
+; CHECK-NEXT:    [[INVARIANT_OP:%.*]] = sext i32 [[NARROW]] to i64
+; CHECK-NEXT:    [[LA2:%.*]] = load i8, ptr @a, align 1
+; CHECK-NEXT:    [[TOBOOL28_NOT:%.*]] = icmp eq i8 [[LA2]], 0
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i8 [[LE2_FR]], 0
+; CHECK-NEXT:    br label [[FOR_COND7_PREHEADER:%.*]]
+; CHECK:       for.cond7.preheader:
+; CHECK-NEXT:    br i1 [[TOBOOL19_NOT4]], label [[FOR_COND7_PREHEADER_SPLIT_US:%.*]], label [[FOR_COND7:%.*]]
+; CHECK:       for.cond7.preheader.split.us:
+; CHECK-NEXT:    br i1 true, label [[FOR_COND7_PREHEADER_SPLIT_US_SPLIT:%.*]], label [[FOR_COND7_US_US:%.*]]
+; CHECK:       for.cond7.us.us:
+; CHECK-NEXT:    br i1 poison, label [[FOR_BODY14_US_US:%.*]], label [[FOR_END25:%.*]]
+; CHECK:       for.body14.us.us:
+; CHECK-NEXT:    br label [[FOR_COND7_US_US]]
+; CHECK:       for.cond7.preheader.split.us.split:
+; CHECK-NEXT:    [[CMP12_US8:%.*]] = icmp slt i64 [[C_PROMOTED22]], [[INVARIANT_OP]]
+; CHECK-NEXT:    br i1 [[CMP12_US8]], label [[FOR_BODY14_US_LR_PH:%.*]], label [[FOR_END25]]
+; CHECK:       for.body14.us.lr.ph:
+; CHECK-NEXT:    br label [[FOR_BODY14_US:%.*]]
+; CHECK:       for.body14.us:
+; CHECK-NEXT:    [[INC246_US10:%.*]] = phi i64 [ [[C_PROMOTED22]], [[FOR_BODY14_US_LR_PH]] ], [ [[INC24_US:%.*]], [[FOR_BODY14_US]] ]
+; CHECK-NEXT:    [[INC24_US]] = add nsw i64 [[INC246_US10]], 1
+; CHECK-NEXT:    [[CMP12_US:%.*]] = icmp slt i64 [[INC24_US]], [[INVARIANT_OP]]
+; CHECK-NEXT:    br i1 [[CMP12_US]], label [[FOR_BODY14_US]], label [[FOR_COND7_US_FOR_END25_SPLIT_US_SPLIT_CRIT_EDGE:%.*]]
+; CHECK:       for.cond7.us.for.end25.split.us.split_crit_edge:
+; CHECK-NEXT:    br label [[FOR_END25]]
+; CHECK:       for.cond7:
+; CHECK-NEXT:    [[INC24_US_LCSSA24:%.*]] = phi i64 [ [[INC24:%.*]], [[FOR_COND15_FOR_INC23_CRIT_EDGE:%.*]] ], [ [[C_PROMOTED22]], [[FOR_COND7_PREHEADER]] ]
+; CHECK-NEXT:    [[ADD9:%.*]] = add nsw i32 [[CONV]], 9
+; CHECK-NEXT:    [[CONV10:%.*]] = sext i32 [[ADD9]] to i64
+; CHECK-NEXT:    [[ADD11:%.*]] = add nsw i64 [[INC24_US_LCSSA24]], [[CONV10]]
+; CHECK-NEXT:    [[CMP12:%.*]] = icmp slt i64 [[ADD11]], 15
+; CHECK-NEXT:    br i1 [[CMP12]], label [[FOR_BODY14:%.*]], label [[FOR_END25]]
+; CHECK:       for.body14:
+; CHECK-NEXT:    br label [[FOR_BODY20:%.*]]
+; CHECK:       for.body20:
+; CHECK-NEXT:    [[STOREMERGE25:%.*]] = phi i16 [ 0, [[FOR_BODY14]] ], [ [[INC21:%.*]], [[FOR_BODY20]] ]
+; CHECK-NEXT:    [[INC21]] = add i16 [[STOREMERGE25]], 1
+; CHECK-NEXT:    [[CONV17:%.*]] = sext i16 [[INC21]] to i32
+; CHECK-NEXT:    [[ADD18:%.*]] = sub nsw i32 0, [[CONV17]]
+; CHECK-NEXT:    [[TOBOOL19_NOT:%.*]] = icmp eq i32 [[CONV]], [[ADD18]]
+; CHECK-NEXT:    br i1 [[TOBOOL19_NOT]], label [[FOR_COND15_FOR_INC23_CRIT_EDGE]], label [[FOR_BODY20]]
+; CHECK:       for.cond15.for.inc23_crit_edge:
+; CHECK-NEXT:    [[INC24]] = add nsw i64 [[INC24_US_LCSSA24]], 1
+; CHECK-NEXT:    br label [[FOR_COND7]]
+; CHECK:       for.end25:
+; CHECK-NEXT:    br label [[IF_END:%.*]]
+; CHECK:       if.end:
+; CHECK-NEXT:    br i1 [[TMP0]], label [[FOR_INC32:%.*]], label [[FOR_INC30_LR_PH:%.*]]
+; CHECK:       for.inc30.lr.ph:
+; CHECK-NEXT:    store i8 [[LA2]], ptr @g, align 1
+; CHECK-NEXT:    br i1 [[TOBOOL28_NOT]], label [[FOR_INC32]], label [[FOR_INC30_LR_PH_SPLIT:%.*]]
+; CHECK:       for.inc30.lr.ph.split:
+; CHECK-NEXT:    br label [[FOR_INC30:%.*]]
+; CHECK:       for.inc30:
+; CHECK-NEXT:    br label [[FOR_INC30]]
+; CHECK:       for.inc32:
+; CHECK-NEXT:    br i1 false, label [[FOR_COND7_PREHEADER]], label [[FOR_END36:%.*]]
+; CHECK:       for.end36:
+; CHECK-NEXT:    ret void
+;
+entry:
+  br label %for.cond5.preheader
+
+for.cond5.preheader:                              ; preds = %entry
+  %le2 = load i8, ptr @g, align 1
+  %conv = sext i8 %le2 to i32
+  %tobool19.not4 = icmp eq i32 %conv, 0
+  %tobool19.not4.fr = freeze i1 %tobool19.not4
+  %k.promoted15 = load i8, ptr @k, align 1
+  %c.promoted22 = load i64, ptr @c, align 4
+  %n.promoted = load i16, ptr @n, align 2
+  %add9.us = add i32 9, %conv
+  %conv10.us = sext i32 %add9.us to i64
+  %invariant.op = sub nsw i64 15, %conv10.us
+  %la2 = load i8, ptr @a, align 1
+  %tobool28.not = icmp eq i8 %la2, 0
+  %lb = load i16, ptr @b, align 2
+  br label %for.cond7.preheader
+
+for.cond7.preheader:                              ; preds = %for.inc32, %for.cond5.preheader
+  %storemerge33 = phi i32 [ -3, %for.cond5.preheader ], [ %conv35, %for.inc32 ]
+  %.pr31432 = phi i8 [ %le2, %for.cond5.preheader ], [ %.pr313, %for.inc32 ]
+  %inc.us.lcssa2131 = phi i8 [ %k.promoted15, %for.cond5.preheader ], [ %inc.us.lcssa16, %for.inc32 ]
+  %inc24.us.lcssa2830 = phi i64 [ %c.promoted22, %for.cond5.preheader ], [ %inc24.us.lcssa23, %for.inc32 ]
+  %p0 = phi i16 [ %n.promoted, %for.cond5.preheader ], [ %p3, %for.inc32 ]
+  %add = add nsw i32 %storemerge33, 8
+  %sm8 = and i32 %storemerge33, 8
+  %cmp.i.i.not = icmp eq i32 %sm8, 0
+  %and2.i.i = and i32 %add, 12
+  %cmp3.i.i = icmp eq i32 %and2.i.i, 0
+  %and7.i.i = and i32 %add, 14
+  %cmp8.i.i = icmp eq i32 %and7.i.i, 0
+  %and12.i.i = and i32 %add, 15
+  %tobool.not.i.i = icmp eq i32 %and12.i.i, 0
+  %..i.i = select i1 %tobool.not.i.i, i32 1, i32 3
+  %xor = xor i32 %storemerge33, 5
+  br i1 %tobool19.not4.fr, label %for.cond7.preheader.split.us, label %for.cond7
+
+for.cond7.preheader.split.us:                     ; preds = %for.cond7.preheader
+  br i1 %cmp.i.i.not, label %for.cond7.us.us, label %for.cond7.preheader.split.us.split
+
+for.cond7.us.us:                                  ; preds = %for.body14.us.us, %for.cond7.preheader.split.us
+  %p1 = phi i16 [ 0, %for.body14.us.us ], [ %p0, %for.cond7.preheader.split.us ]
+  %inc24.us.lcssa27 = phi i64 [ %inc24.us.us, %for.body14.us.us ], [ %inc24.us.lcssa2830, %for.cond7.preheader.split.us ]
+  %inc.us.lcssa20 = phi i8 [ %inc.us.us, %for.body14.us.us ], [ %inc.us.lcssa2131, %for.cond7.preheader.split.us ]
+  %spec.select = select i1 %cmp8.i.i, i32 2, i32 %..i.i
+  %retval.0.i.i.us.us = select i1 %cmp3.i.i, i32 1, i32 %spec.select
+  %add8.us.us = add i32 %retval.0.i.i.us.us, 9
+  %add9.us.us = add i32 %add8.us.us, %conv
+  %conv10.us.us = sext i32 %add9.us.us to i64
+  %add11.us.us = add nsw i64 %conv10.us.us, %inc24.us.lcssa27
+  %cmp12.us.us = icmp slt i64 %add11.us.us, 15
+  br i1 %cmp12.us.us, label %for.body14.us.us, label %for.end25
+
+for.body14.us.us:                                 ; preds = %for.cond7.us.us
+  %inc.us.us = add i8 %inc.us.lcssa20, 1
+  %inc24.us.us = add nsw i64 %inc24.us.lcssa27, 1
+  br label %for.cond7.us.us
+
+for.cond7.preheader.split.us.split:               ; preds = %for.cond7.preheader.split.us
+  %cmp12.us8 = icmp slt i64 %inc24.us.lcssa2830, %invariant.op
+  br i1 %cmp12.us8, label %for.body14.us.lr.ph, label %for.end25
+
+for.body14.us.lr.ph:                              ; preds = %for.cond7.preheader.split.us.split
+  br label %for.body14.us
+
+for.body14.us:                                    ; preds = %for.body14.us, %for.body14.us.lr.ph
+  %inc246.us10 = phi i64 [ %inc24.us.lcssa2830, %for.body14.us.lr.ph ], [ %inc24.us, %for.body14.us ]
+  %inc7.us9 = phi i8 [ %inc.us.lcssa2131, %for.body14.us.lr.ph ], [ %inc.us, %for.body14.us ]
+  %inc.us = add i8 %inc7.us9, 1
+  %inc24.us = add nsw i64 %inc246.us10, 1
+  %cmp12.us = icmp slt i64 %inc24.us, %invariant.op
+  br i1 %cmp12.us, label %for.body14.us, label %for.cond7.us.for.end25.split.us.split_crit_edge
+
+for.cond7.us.for.end25.split.us.split_crit_edge:  ; preds = %for.body14.us
+  %inc24.us.lcssa = phi i64 [ %inc24.us, %for.body14.us ]
+  %inc.us.lcssa = phi i8 [ %inc.us, %for.body14.us ]
+  br label %for.end25
+
+for.cond7:                                        ; preds = %for.cond15.for.inc23_crit_edge, %for.cond7.preheader
+  %p2 = phi i16 [ %split, %for.cond15.for.inc23_crit_edge ], [ %p0, %for.cond7.preheader ]
+  %inc24.us.lcssa24 = phi i64 [ %inc24, %for.cond15.for.inc23_crit_edge ], [ %inc24.us.lcssa2830, %for.cond7.preheader ]
+  %inc.us.lcssa17 = phi i8 [ %inc, %for.cond15.for.inc23_crit_edge ], [ %inc.us.lcssa2131, %for.cond7.preheader ]
+  %cmp.i.i.not.not = xor i1 %cmp.i.i.not, true
+  %brmerge = select i1 %cmp.i.i.not.not, i1 true, i1 %cmp3.i.i
+  %.mux = select i1 %cmp.i.i.not.not, i32 0, i32 1
+  %spec.select34 = select i1 %cmp8.i.i, i32 2, i32 %..i.i
+  %retval.0.i.i = select i1 %brmerge, i32 %.mux, i32 %spec.select34
+  %add8 = add i32 %retval.0.i.i, 9
+  %add9 = add i32 %add8, %conv
+  %conv10 = sext i32 %add9 to i64
+  %add11 = add nsw i64 %conv10, %inc24.us.lcssa24
+  %cmp12 = icmp slt i64 %add11, 15
+  br i1 %cmp12, label %for.body14, label %for.end25
+
+for.body14:                                       ; preds = %for.cond7
+  %inc = add i8 %inc.us.lcssa17, 1
+  br label %for.body20
+
+for.body20:                                       ; preds = %for.body20, %for.body14
+  %storemerge25 = phi i16 [ 0, %for.body14 ], [ %inc21, %for.body20 ]
+  %inc21 = add i16 %storemerge25, 1
+  %conv17 = sext i16 %inc21 to i32
+  %add18 = sub nsw i32 0, %conv17
+  %tobool19.not = icmp eq i32 %conv, %add18
+  br i1 %tobool19.not, label %for.cond15.for.inc23_crit_edge, label %for.body20
+
+for.cond15.for.inc23_crit_edge:                   ; preds = %for.body20
+  %split = phi i16 [ %inc21, %for.body20 ]
+  %inc24 = add nsw i64 %inc24.us.lcssa24, 1
+  br label %for.cond7
+
+for.end25:                                        ; preds = %for.cond7, %for.cond7.us.for.end25.split.us.split_crit_edge, %for.cond7.preheader.split.us.split, %for.cond7.us.us
+  %p3 = phi i16 [ %p1, %for.cond7.us.us ], [ 0, %for.cond7.us.for.end25.split.us.split_crit_edge ], [ %p0, %for.cond7.preheader.split.us.split ], [ %p2, %for.cond7 ]
+  %inc24.us.lcssa23 = phi i64 [ %inc24.us.lcssa27, %for.cond7.us.us ], [ %inc24.us.lcssa, %for.cond7.us.for.end25.split.us.split_crit_edge ], [ %inc24.us.lcssa2830, %for.cond7.preheader.split.us.split ], [ %inc24.us.lcssa24, %for.cond7 ]
+  %inc.us.lcssa16 = phi i8 [ %inc.us.lcssa20, %for.cond7.us.us ], [ %inc.us.lcssa, %for.cond7.us.for.end25.split.us.split_crit_edge ], [ %inc.us.lcssa2131, %for.cond7.preheader.split.us.split ], [ %inc.us.lcssa17, %for.cond7 ]
+  %tobool26.not = icmp eq i16 %p3, 0
+  br label %if.end
+
+if.end:                                           ; preds = %for.end25
+  %tobool28.not11 = icmp eq i8 %.pr31432, 0
+  br i1 %tobool28.not11, label %for.inc32, label %for.inc30.lr.ph
+
+for.inc30.lr.ph:                                  ; preds = %if.end
+  store i8 %la2, ptr @g, align 1
+  br i1 %tobool28.not, label %for.inc32, label %for.inc30.lr.ph.split
+
+for.inc30.lr.ph.split:                            ; preds = %for.inc30.lr.ph
+  %storemerge.lcssa12 = phi i32 [ %storemerge33, %for.inc30.lr.ph ]
+  br label %for.inc30
+
+for.inc30:                                        ; preds = %for.inc30, %for.inc30.lr.ph.split
+  br label %for.inc30
+
+for.inc32:                                        ; preds = %for.inc30.lr.ph, %if.end
+  %.pr313 = phi i8 [ %.pr31432, %if.end ], [ %la2, %for.inc30.lr.ph ]
+  %conv33 = trunc i32 %storemerge33 to i16
+  %add.i = add i16 %lb, %conv33
+  %conv35 = zext i16 %add.i to i32
+  %cmp = icmp slt i32 %conv35, 0
+  br i1 %cmp, label %for.cond7.preheader, label %for.end36
+
+for.end36:                                        ; preds = %for.inc32
+  %storemerge.lcssa = phi i32 [ %conv35, %for.inc32 ]
+  ret void
+
+; uselistorder directives
+  uselistorder i32 %storemerge33, { 2, 4, 1, 3, 0 }
+}
----------------
nikic wrote:

Hm yeah, for some reason llvm-reduce is completely ineffective for this case. What worked for me is to manually remove uses of storemerge33 and then reorder them so the uselistorder is no longer necessary, and then run llvm-reduce afterwards. This gave me: https://gist.github.com/nikic/da8251d05a5df6038bd3e2eb773f64c0 This is probably still nowhere near minimal, but maybe good enough for a test case.

https://github.com/llvm/llvm-project/pull/71489


More information about the llvm-commits mailing list