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

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 7 12:10:41 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:

What kind of interestingness test were you using? Diff between two opt binaries?

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


More information about the llvm-commits mailing list