2184 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py2; RUN: opt < %s -S -disable-output "-passes=print<scalar-evolution>" 2>&1 | FileCheck %s3 4; Positive and negative tests for inferring flags like nsw from5; reasoning about how a poison value from overflow would trigger6; undefined behavior.7 8define void @foo() {9; CHECK-LABEL: 'foo'10; CHECK-NEXT: Classifying expressions for: @foo11; CHECK-NEXT: Determining loop execution counts for: @foo12;13 ret void14}15 16; Example where an add should get the nsw flag, so that a sext can be17; distributed over the add.18define void @test-add-nsw(ptr %input, i32 %offset, i32 %numIterations) {19; CHECK-LABEL: 'test-add-nsw'20; CHECK-NEXT: Classifying expressions for: @test-add-nsw21; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]22; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }23; CHECK-NEXT: %index32 = add nsw i32 %i, %offset24; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }25; CHECK-NEXT: %index64 = sext i32 %index32 to i6426; CHECK-NEXT: --> {(sext i32 %offset to i64),+,1}<nsw><%loop> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: ((zext i32 (-1 + %numIterations) to i64) + (sext i32 %offset to i64)) LoopDispositions: { %loop: Computable }27; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index6428; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }29; CHECK-NEXT: %nexti = add nsw i32 %i, 130; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }31; CHECK-NEXT: Determining loop execution counts for: @test-add-nsw32; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)33; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -134; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)35; CHECK-NEXT: Loop %loop: Trip multiple is 136;37entry:38 br label %loop39loop:40 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]41 42 %index32 = add nsw i32 %i, %offset43 44 %index64 = sext i32 %index32 to i6445 46 %ptr = getelementptr inbounds float, ptr %input, i64 %index6447 %nexti = add nsw i32 %i, 148 %f = load float, ptr %ptr, align 449 call void @foo()50 %exitcond = icmp eq i32 %nexti, %numIterations51 br i1 %exitcond, label %exit, label %loop52exit:53 ret void54}55 56; Example where an add should get the nuw flag.57define void @test-add-nuw(ptr %input, i32 %offset, i32 %numIterations) {58; CHECK-LABEL: 'test-add-nuw'59; CHECK-NEXT: Classifying expressions for: @test-add-nuw60; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]61; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }62; CHECK-NEXT: %index32 = add nuw i32 %i, %offset63; CHECK-NEXT: --> {%offset,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }64; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index3265; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }66; CHECK-NEXT: %nexti = add nuw i32 %i, 167; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }68; CHECK-NEXT: Determining loop execution counts for: @test-add-nuw69; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)70; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -171; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)72; CHECK-NEXT: Loop %loop: Trip multiple is 173;74entry:75 br label %loop76loop:77 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]78 79 %index32 = add nuw i32 %i, %offset80 81 %ptr = getelementptr inbounds float, ptr %input, i32 %index3282 %nexti = add nuw i32 %i, 183 %f = load float, ptr %ptr, align 484 %exitcond = icmp eq i32 %nexti, %numIterations85 br i1 %exitcond, label %exit, label %loop86 87exit:88 ret void89}90 91; Case where we're checking to see if add flags are valid in defining scope92; and all operands (other than addrec) are invariant93define void @test-add-scope-invariant(ptr %input, i32 %needle) {94; CHECK-LABEL: 'test-add-scope-invariant'95; CHECK-NEXT: Classifying expressions for: @test-add-scope-invariant96; CHECK-NEXT: %offset = load i32, ptr %input, align 497; CHECK-NEXT: --> %offset U: full-set S: full-set98; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]99; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + (-1 * %offset) + %needle) LoopDispositions: { %loop: Computable }100; CHECK-NEXT: %i.next = add nuw i32 %i, 1101; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: ((-1 * %offset) + %needle) LoopDispositions: { %loop: Computable }102; CHECK-NEXT: %of_interest = add nuw nsw i32 %i.next, %offset103; CHECK-NEXT: --> {(1 + %offset)<nuw><nsw>,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %needle LoopDispositions: { %loop: Computable }104; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %of_interest105; CHECK-NEXT: --> ((4 * (sext i32 {(1 + %offset)<nuw><nsw>,+,1}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 %needle to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }106; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-invariant107; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %offset) + %needle)108; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1109; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %offset) + %needle)110; CHECK-NEXT: Loop %loop: Trip multiple is 1111;112entry:113 %offset = load i32, ptr %input114 br label %loop115loop:116 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]117 %i.next = add nuw i32 %i, 1118 %of_interest = add nuw nsw i32 %i.next, %offset119 %gep2 = getelementptr i32, ptr %input, i32 %of_interest120 store i32 0, ptr %gep2121 %exitcond = icmp eq i32 %of_interest, %needle122 br i1 %exitcond, label %exit, label %loop123 124exit:125 ret void126}127 128; Case where we're checking to see if add flags are valid in defining scope129; and other operands are *not* invariant.130define void @test-add-scope-bound(ptr %input, i32 %needle) {131; CHECK-LABEL: 'test-add-scope-bound'132; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound133; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]134; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }135; CHECK-NEXT: %gep = getelementptr i32, ptr %input, i32 %i136; CHECK-NEXT: --> ((4 * (sext i32 {0,+,1}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }137; CHECK-NEXT: %offset = load i32, ptr %gep, align 4138; CHECK-NEXT: --> %offset U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }139; CHECK-NEXT: %i.next = add nuw i32 %i, 1140; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }141; CHECK-NEXT: %of_interest = add nuw nsw i32 %i.next, %offset142; CHECK-NEXT: --> ({1,+,1}<nuw><%loop> + %offset)<nuw><nsw> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }143; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %of_interest144; CHECK-NEXT: --> ((4 * ((sext i32 {1,+,1}<nuw><%loop> to i64) + (sext i32 %offset to i64))<nsw>)<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }145; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound146; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.147; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.148; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.149;150entry:151 br label %loop152loop:153 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]154 %gep = getelementptr i32, ptr %input, i32 %i155 %offset = load i32, ptr %gep156 %i.next = add nuw i32 %i, 1157 %of_interest = add nuw nsw i32 %i.next, %offset158 %gep2 = getelementptr i32, ptr %input, i32 %of_interest159 store i32 0, ptr %gep2160 %exitcond = icmp eq i32 %of_interest, %needle161 br i1 %exitcond, label %exit, label %loop162 163exit:164 ret void165}166 167define void @test-add-scope-bound-unkn-preheader(ptr %input, i32 %needle) {168; CHECK-LABEL: 'test-add-scope-bound-unkn-preheader'169; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-preheader170; CHECK-NEXT: %offset = load i32, ptr %input, align 4171; CHECK-NEXT: --> %offset U: full-set S: full-set172; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]173; CHECK-NEXT: --> {0,+,%offset}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }174; CHECK-NEXT: %i.next = add nuw i32 %i, %offset175; CHECK-NEXT: --> {%offset,+,%offset}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }176; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next177; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,%offset}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }178; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-preheader179; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.180; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.181; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.182;183entry:184 %offset = load i32, ptr %input185 br label %loop186loop:187 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]188 %i.next = add nuw i32 %i, %offset189 %gep2 = getelementptr i32, ptr %input, i32 %i.next190 store i32 0, ptr %gep2191 %exitcond = icmp eq i32 %i.next, %needle192 br i1 %exitcond, label %exit, label %loop193 194exit:195 ret void196}197 198define void @test-add-scope-bound-unkn-preheader-neg1(ptr %input, i32 %needle) {199; CHECK-LABEL: 'test-add-scope-bound-unkn-preheader-neg1'200; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-preheader-neg1201; CHECK-NEXT: %offset = load i32, ptr %input, align 4202; CHECK-NEXT: --> %offset U: full-set S: full-set203; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]204; CHECK-NEXT: --> {0,+,%offset}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }205; CHECK-NEXT: %i.next = add nuw i32 %i, %offset206; CHECK-NEXT: --> {%offset,+,%offset}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }207; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next208; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,%offset}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }209; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-preheader-neg1210; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.211; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.212; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.213;214entry:215 %offset = load i32, ptr %input216 call void @foo()217 br label %loop218loop:219 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]220 %i.next = add nuw i32 %i, %offset221 %gep2 = getelementptr i32, ptr %input, i32 %i.next222 store i32 0, ptr %gep2223 %exitcond = icmp eq i32 %i.next, %needle224 br i1 %exitcond, label %exit, label %loop225 226exit:227 ret void228}229 230define void @test-add-scope-bound-unkn-preheader-neg2(ptr %input, i32 %needle) {231; CHECK-LABEL: 'test-add-scope-bound-unkn-preheader-neg2'232; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-preheader-neg2233; CHECK-NEXT: %offset = load i32, ptr %input, align 4234; CHECK-NEXT: --> %offset U: full-set S: full-set235; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]236; CHECK-NEXT: --> {0,+,%offset}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }237; CHECK-NEXT: %i.next = add nuw i32 %i, %offset238; CHECK-NEXT: --> {%offset,+,%offset}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }239; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next240; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,%offset}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }241; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-preheader-neg2242; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.243; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.244; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.245;246entry:247 %offset = load i32, ptr %input248 br label %loop249loop:250 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]251 call void @foo()252 %i.next = add nuw i32 %i, %offset253 %gep2 = getelementptr i32, ptr %input, i32 %i.next254 store i32 0, ptr %gep2255 %exitcond = icmp eq i32 %i.next, %needle256 br i1 %exitcond, label %exit, label %loop257 258exit:259 ret void260}261 262 263define void @test-add-scope-bound-unkn-header(ptr %input, i32 %needle) {264; CHECK-LABEL: 'test-add-scope-bound-unkn-header'265; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-header266; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]267; CHECK-NEXT: --> %i U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }268; CHECK-NEXT: %gep = getelementptr i32, ptr %input, i32 %i269; CHECK-NEXT: --> ((4 * (sext i32 %i to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }270; CHECK-NEXT: %offset = load i32, ptr %gep, align 4271; CHECK-NEXT: --> %offset U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }272; CHECK-NEXT: %i.next = add nuw i32 %i, %offset273; CHECK-NEXT: --> (%offset + %i)<nuw> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }274; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next275; CHECK-NEXT: --> ((4 * (sext i32 (%offset + %i)<nuw> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }276; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-header277; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.278; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.279; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.280;281entry:282 br label %loop283loop:284 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]285 %gep = getelementptr i32, ptr %input, i32 %i286 %offset = load i32, ptr %gep287 %i.next = add nuw i32 %i, %offset288 %gep2 = getelementptr i32, ptr %input, i32 %i.next289 store i32 0, ptr %gep2290 %exitcond = icmp eq i32 %i.next, %needle291 br i1 %exitcond, label %exit, label %loop292 293exit:294 ret void295}296 297define void @test-add-scope-bound-unkn-header2(ptr %input, i32 %needle) {298; CHECK-LABEL: 'test-add-scope-bound-unkn-header2'299; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-header2300; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]301; CHECK-NEXT: --> %i U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }302; CHECK-NEXT: %gep = getelementptr i32, ptr %input, i32 %i303; CHECK-NEXT: --> ((4 * (sext i32 %i to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }304; CHECK-NEXT: %offset = load i32, ptr %gep, align 4305; CHECK-NEXT: --> %offset U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }306; CHECK-NEXT: %i.next = add nuw i32 %i, %offset307; CHECK-NEXT: --> (%offset + %i)<nuw> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }308; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next309; CHECK-NEXT: --> ((4 * (sext i32 (%offset + %i)<nuw> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }310; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-header2311; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.312; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.313; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.314;315entry:316 br label %loop317loop:318 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]319 call void @foo()320 %gep = getelementptr i32, ptr %input, i32 %i321 %offset = load i32, ptr %gep322 %i.next = add nuw i32 %i, %offset323 %gep2 = getelementptr i32, ptr %input, i32 %i.next324 store i32 0, ptr %gep2325 %exitcond = icmp eq i32 %i.next, %needle326 br i1 %exitcond, label %exit, label %loop327 328exit:329 ret void330}331 332define void @test-add-scope-bound-unkn-header-neg(ptr %input, i32 %needle) {333; CHECK-LABEL: 'test-add-scope-bound-unkn-header-neg'334; CHECK-NEXT: Classifying expressions for: @test-add-scope-bound-unkn-header-neg335; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]336; CHECK-NEXT: --> %i U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }337; CHECK-NEXT: %gep = getelementptr i32, ptr %input, i32 %i338; CHECK-NEXT: --> ((4 * (sext i32 %i to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }339; CHECK-NEXT: %offset = load i32, ptr %gep, align 4340; CHECK-NEXT: --> %offset U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }341; CHECK-NEXT: %i.next = add nuw i32 %i, %offset342; CHECK-NEXT: --> (%offset + %i) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }343; CHECK-NEXT: %gep2 = getelementptr i32, ptr %input, i32 %i.next344; CHECK-NEXT: --> ((4 * (sext i32 (%offset + %i) to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }345; CHECK-NEXT: Determining loop execution counts for: @test-add-scope-bound-unkn-header-neg346; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.347; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.348; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.349;350entry:351 br label %loop352loop:353 %i = phi i32 [ %i.next, %loop ], [ 0, %entry ]354 %gep = getelementptr i32, ptr %input, i32 %i355 %offset = load i32, ptr %gep356 call void @foo()357 %i.next = add nuw i32 %i, %offset358 %gep2 = getelementptr i32, ptr %input, i32 %i.next359 store i32 0, ptr %gep2360 %exitcond = icmp eq i32 %i.next, %needle361 br i1 %exitcond, label %exit, label %loop362 363exit:364 ret void365}366 367define void @test-add-nuw-from-icmp(ptr %input, i32 %offset,368; CHECK-LABEL: 'test-add-nuw-from-icmp'369; CHECK-NEXT: Classifying expressions for: @test-add-nuw-from-icmp370; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]371; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }372; CHECK-NEXT: %index32 = add nuw i32 %i, %offset373; CHECK-NEXT: --> {%offset,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }374; CHECK-NEXT: %cmp.idx = sext i1 %cmp to i32375; CHECK-NEXT: --> (sext i1 %cmp to i32) U: [-1,1) S: [-1,1) Exits: <<Unknown>> LoopDispositions: { %loop: Variant }376; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %cmp.idx377; CHECK-NEXT: --> ((4 * (sext i1 %cmp to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }378; CHECK-NEXT: %nexti = add nuw i32 %i, 1379; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }380; CHECK-NEXT: Determining loop execution counts for: @test-add-nuw-from-icmp381; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)382; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1383; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)384; CHECK-NEXT: Loop %loop: Trip multiple is 1385;386 i32 %numIterations) {387entry:388 br label %loop389loop:390 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]391 392 %index32 = add nuw i32 %i, %offset393 %cmp = icmp sgt i32 %index32, 0394 %cmp.idx = sext i1 %cmp to i32395 396 %ptr = getelementptr inbounds float, ptr %input, i32 %cmp.idx397 %nexti = add nuw i32 %i, 1398 %f = load float, ptr %ptr, align 4399 %exitcond = icmp eq i32 %nexti, %numIterations400 br i1 %exitcond, label %exit, label %loop401 402exit:403 ret void404}405 406; With no load to trigger UB from poison, we cannot infer nsw.407define void @test-add-no-load(ptr %input, i32 %offset, i32 %numIterations) {408; CHECK-LABEL: 'test-add-no-load'409; CHECK-NEXT: Classifying expressions for: @test-add-no-load410; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]411; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }412; CHECK-NEXT: %index32 = add nsw i32 %i, %offset413; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }414; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32415; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }416; CHECK-NEXT: %nexti = add nuw i32 %i, 1417; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }418; CHECK-NEXT: Determining loop execution counts for: @test-add-no-load419; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)420; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1421; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)422; CHECK-NEXT: Loop %loop: Trip multiple is 1423;424entry:425 br label %loop426loop:427 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]428 429 %index32 = add nsw i32 %i, %offset430 431 %ptr = getelementptr inbounds float, ptr %input, i32 %index32432 %nexti = add nuw i32 %i, 1433 %exitcond = icmp eq i32 %nexti, %numIterations434 br i1 %exitcond, label %exit, label %loop435 436exit:437 ret void438}439 440; The current code is only supposed to look at the loop header, so441; it should not infer nsw in this case, as that would require looking442; outside the loop header.443define void @test-add-not-header(ptr %input, i32 %offset, i32 %numIterations) {444; CHECK-LABEL: 'test-add-not-header'445; CHECK-NEXT: Classifying expressions for: @test-add-not-header446; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]447; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }448; CHECK-NEXT: %index32 = add nsw i32 %i, %offset449; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }450; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32451; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }452; CHECK-NEXT: %nexti = add nsw i32 %i, 1453; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }454; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header455; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)456; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1457; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)458; CHECK-NEXT: Loop %loop: Trip multiple is 1459;460entry:461 br label %loop462loop:463 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]464 br label %loop2465loop2:466 467 %index32 = add nsw i32 %i, %offset468 469 %ptr = getelementptr inbounds float, ptr %input, i32 %index32470 %nexti = add nsw i32 %i, 1471 %f = load float, ptr %ptr, align 4472 %exitcond = icmp eq i32 %nexti, %numIterations473 br i1 %exitcond, label %exit, label %loop474exit:475 ret void476}477 478; Same thing as test-add-not-header, but in this case only the load479; instruction is outside the loop header.480define void @test-add-not-header2(ptr %input, i32 %offset, i32 %numIterations) {481; CHECK-LABEL: 'test-add-not-header2'482; CHECK-NEXT: Classifying expressions for: @test-add-not-header2483; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]484; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }485; CHECK-NEXT: %index32 = add nsw i32 %i, %offset486; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }487; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32488; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }489; CHECK-NEXT: %nexti = add nsw i32 %i, 1490; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }491; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header2492; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)493; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1494; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)495; CHECK-NEXT: Loop %loop: Trip multiple is 1496;497entry:498 br label %loop499loop:500 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]501 502 %index32 = add nsw i32 %i, %offset503 504 %ptr = getelementptr inbounds float, ptr %input, i32 %index32505 %nexti = add nsw i32 %i, 1506 br label %loop2507loop2:508 %f = load float, ptr %ptr, align 4509 %exitcond = icmp eq i32 %nexti, %numIterations510 br i1 %exitcond, label %exit, label %loop511exit:512 ret void513}514 515; Similar to test-add-not-header, but in this case the load516; instruction may not be executed.517define void @test-add-not-header3(ptr %input, i32 %offset, i32 %numIterations,518; CHECK-LABEL: 'test-add-not-header3'519; CHECK-NEXT: Classifying expressions for: @test-add-not-header3520; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]521; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }522; CHECK-NEXT: %index32 = add nsw i32 %i, %offset523; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }524; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32525; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }526; CHECK-NEXT: %nexti = add nsw i32 %i, 1527; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }528; CHECK-NEXT: %cond = load volatile i1, ptr %cond_buf, align 1529; CHECK-NEXT: --> %cond U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }530; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header3531; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.532; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***533; CHECK-NEXT: exit count for loop2: (-1 + %numIterations)534; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1535; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)536; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***537; CHECK-NEXT: symbolic max exit count for loop2: (-1 + %numIterations)538;539 ptr %cond_buf) {540entry:541 br label %loop542loop:543 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]544 545 %index32 = add nsw i32 %i, %offset546 547 %ptr = getelementptr inbounds float, ptr %input, i32 %index32548 %nexti = add nsw i32 %i, 1549 %cond = load volatile i1, ptr %cond_buf550 br i1 %cond, label %loop2, label %exit551loop2:552 %f = load float, ptr %ptr, align 4553 %exitcond = icmp eq i32 %nexti, %numIterations554 br i1 %exitcond, label %exit, label %loop555exit:556 ret void557}558 559; Same thing as test-add-not-header2, except we have a few extra560; blocks.561define void @test-add-not-header4(ptr %input, i32 %offset, i32 %numIterations) {562; CHECK-LABEL: 'test-add-not-header4'563; CHECK-NEXT: Classifying expressions for: @test-add-not-header4564; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]565; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }566; CHECK-NEXT: %index32 = add nsw i32 %i, %offset567; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }568; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32569; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }570; CHECK-NEXT: %nexti = add nsw i32 %i, 1571; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }572; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header4573; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)574; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1575; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)576; CHECK-NEXT: Loop %loop: Trip multiple is 1577;578entry:579 br label %loop580loop:581 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]582 583 %index32 = add nsw i32 %i, %offset584 585 %ptr = getelementptr inbounds float, ptr %input, i32 %index32586 %nexti = add nsw i32 %i, 1587 br label %loop3588loop3:589 br label %loop4590loop4:591 br label %loop2592loop2:593 %f = load float, ptr %ptr, align 4594 %exitcond = icmp eq i32 %nexti, %numIterations595 br i1 %exitcond, label %exit, label %loop596exit:597 ret void598}599 600; Demonstrate why we need a Visited set in llvm::programUndefinedIfPoison.601define void @test-add-not-header5(ptr %input, i32 %offset) {602; CHECK-LABEL: 'test-add-not-header5'603; CHECK-NEXT: Classifying expressions for: @test-add-not-header5604; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]605; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }606; CHECK-NEXT: %index32 = add nsw i32 %i, %offset607; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }608; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32609; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }610; CHECK-NEXT: %nexti = add nsw i32 %i, 1611; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }612; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header5613; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.614; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.615; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.616;617entry:618 br label %loop619loop:620 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]621 622 %index32 = add nsw i32 %i, %offset623 624 %ptr = getelementptr inbounds float, ptr %input, i32 %index32625 %nexti = add nsw i32 %i, 1626 br label %loop627 628exit:629 ret void630}631 632; Variant where a separate IV is used for the load.633define void @test-add-not-header6(ptr %input, i32 %offset, i32 %numIterations) {634; CHECK-LABEL: 'test-add-not-header6'635; CHECK-NEXT: Classifying expressions for: @test-add-not-header6636; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]637; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }638; CHECK-NEXT: %i2 = phi i32 [ %nexti2, %loop2 ], [ %offset, %entry ]639; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }640; CHECK-NEXT: %nexti = add nsw i32 %i, 1641; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }642; CHECK-NEXT: %nexti2 = add nsw i32 %i2, 1643; CHECK-NEXT: --> {(1 + %offset),+,1}<nsw><%loop> U: full-set S: full-set Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable }644; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2645; CHECK-NEXT: --> {((4 * (sext i32 (1 + %offset) to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 (1 + %offset) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }646; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header6647; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)648; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1649; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)650; CHECK-NEXT: Loop %loop: Trip multiple is 1651;652entry:653 br label %loop654loop:655 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]656 %i2 = phi i32 [ %nexti2, %loop2 ], [ %offset, %entry ]657 br label %loop2658loop2:659 %nexti = add nsw i32 %i, 1660 %nexti2 = add nsw i32 %i2, 1661 %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2662 %f = load float, ptr %ptr, align 4663 %exitcond = icmp eq i32 %nexti, %numIterations664 br i1 %exitcond, label %exit, label %loop665exit:666 ret void667}668 669; Variant where the loop latch is not exiting.670define void @test-add-not-header7(ptr %input, i32 %offset, i32 %numIterations) {671; CHECK-LABEL: 'test-add-not-header7'672; CHECK-NEXT: Classifying expressions for: @test-add-not-header7673; CHECK-NEXT: %i = phi i32 [ %nexti, %loop.latch ], [ 0, %entry ]674; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }675; CHECK-NEXT: %i2 = phi i32 [ %nexti2, %loop.latch ], [ %offset, %entry ]676; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }677; CHECK-NEXT: %nexti = add nsw i32 %i, 1678; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }679; CHECK-NEXT: %nexti2 = add nsw i32 %i2, 1680; CHECK-NEXT: --> {(1 + %offset),+,1}<nsw><%loop> U: full-set S: full-set Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable }681; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2682; CHECK-NEXT: --> {((4 * (sext i32 (1 + %offset) to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 (1 + %offset) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }683; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header7684; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)685; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1686; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)687; CHECK-NEXT: Loop %loop: Trip multiple is 1688;689entry:690 br label %loop691loop:692 %i = phi i32 [ %nexti, %loop.latch ], [ 0, %entry ]693 %i2 = phi i32 [ %nexti2, %loop.latch ], [ %offset, %entry ]694 br label %loop2695loop2:696 %nexti = add nsw i32 %i, 1697 %nexti2 = add nsw i32 %i2, 1698 %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2699 %f = load float, ptr %ptr, align 4700 %exitcond = icmp eq i32 %nexti, %numIterations701 br i1 %exitcond, label %exit, label %loop.latch702loop.latch:703 br label %loop704exit:705 ret void706}707 708; Variant where the load is after the exit.709define void @test-add-not-header8(ptr %input, i32 %offset, i32 %numIterations) {710; CHECK-LABEL: 'test-add-not-header8'711; CHECK-NEXT: Classifying expressions for: @test-add-not-header8712; CHECK-NEXT: %i = phi i32 [ %nexti, %loop.latch ], [ 0, %entry ]713; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }714; CHECK-NEXT: %i2 = phi i32 [ %nexti2, %loop.latch ], [ %offset, %entry ]715; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }716; CHECK-NEXT: %nexti = add nsw i32 %i, 1717; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }718; CHECK-NEXT: %nexti2 = add nsw i32 %i2, 1719; CHECK-NEXT: --> {(1 + %offset),+,1}<nw><%loop> U: full-set S: full-set Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable }720; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2721; CHECK-NEXT: --> ((4 * (sext i32 {(1 + %offset),+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (%offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }722; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header8723; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)724; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1725; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)726; CHECK-NEXT: Loop %loop: Trip multiple is 1727;728entry:729 br label %loop730loop:731 %i = phi i32 [ %nexti, %loop.latch ], [ 0, %entry ]732 %i2 = phi i32 [ %nexti2, %loop.latch ], [ %offset, %entry ]733 br label %loop2734loop2:735 %nexti = add nsw i32 %i, 1736 %nexti2 = add nsw i32 %i2, 1737 %exitcond = icmp eq i32 %nexti, %numIterations738 br i1 %exitcond, label %exit, label %loop.latch739loop.latch:740 %ptr = getelementptr inbounds float, ptr %input, i32 %nexti2741 %f = load float, ptr %ptr, align 4742 br label %loop743exit:744 ret void745}746 747; The call instruction makes it not guaranteed that the add will be748; executed, since it could run forever or throw an exception, so we749; cannot assume that the UB is realized.750define void @test-add-call(ptr %input, i32 %offset, i32 %numIterations) {751; CHECK-LABEL: 'test-add-call'752; CHECK-NEXT: Classifying expressions for: @test-add-call753; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]754; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }755; CHECK-NEXT: %index32 = add nsw i32 %i, %offset756; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }757; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32758; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }759; CHECK-NEXT: %nexti = add nsw i32 %i, 1760; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }761; CHECK-NEXT: Determining loop execution counts for: @test-add-call762; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)763; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1764; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)765; CHECK-NEXT: Loop %loop: Trip multiple is 1766;767entry:768 br label %loop769loop:770 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]771 772 call void @foo()773 %index32 = add nsw i32 %i, %offset774 775 %ptr = getelementptr inbounds float, ptr %input, i32 %index32776 %nexti = add nsw i32 %i, 1777 %f = load float, ptr %ptr, align 4778 %exitcond = icmp eq i32 %nexti, %numIterations779 br i1 %exitcond, label %exit, label %loop780exit:781 ret void782}783 784; Same issue as test-add-call, but this time the call is between the785; producer of poison and the load that consumes it.786define void @test-add-call2(ptr %input, i32 %offset, i32 %numIterations) {787; CHECK-LABEL: 'test-add-call2'788; CHECK-NEXT: Classifying expressions for: @test-add-call2789; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]790; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }791; CHECK-NEXT: %index32 = add nsw i32 %i, %offset792; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }793; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index32794; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<nw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }795; CHECK-NEXT: %nexti = add nsw i32 %i, 1796; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }797; CHECK-NEXT: Determining loop execution counts for: @test-add-call2798; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)799; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1800; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)801; CHECK-NEXT: Loop %loop: Trip multiple is 1802;803entry:804 br label %loop805loop:806 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]807 808 %index32 = add nsw i32 %i, %offset809 810 %ptr = getelementptr inbounds float, ptr %input, i32 %index32811 %nexti = add nsw i32 %i, 1812 call void @foo()813 %f = load float, ptr %ptr, align 4814 %exitcond = icmp eq i32 %nexti, %numIterations815 br i1 %exitcond, label %exit, label %loop816exit:817 ret void818}819 820; Any poison input makes getelementptr produce poison821define void @test-gep-propagates-poison(ptr %input, i32 %offset, i32 %numIterations) {822; CHECK-LABEL: 'test-gep-propagates-poison'823; CHECK-NEXT: Classifying expressions for: @test-gep-propagates-poison824; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]825; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }826; CHECK-NEXT: %index32 = add nsw i32 %i, %offset827; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }828; CHECK-NEXT: %ptr = getelementptr float, ptr %input, i32 %index32829; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }830; CHECK-NEXT: %nexti = add nsw i32 %i, 1831; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }832; CHECK-NEXT: Determining loop execution counts for: @test-gep-propagates-poison833; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)834; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1835; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)836; CHECK-NEXT: Loop %loop: Trip multiple is 1837;838entry:839 br label %loop840loop:841 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]842 843 %index32 = add nsw i32 %i, %offset844 845 %ptr = getelementptr float, ptr %input, i32 %index32846 %nexti = add nsw i32 %i, 1847 %f = load float, ptr %ptr, align 4848 %exitcond = icmp eq i32 %nexti, %numIterations849 br i1 %exitcond, label %exit, label %loop850exit:851 ret void852}853 854; Multiplication by a non-zero constant propagates poison if there is855; a nuw or nsw flag on the multiplication.856define void @test-add-mul-propagates(ptr %input, i32 %offset, i32 %numIterations) {857; CHECK-LABEL: 'test-add-mul-propagates'858; CHECK-NEXT: Classifying expressions for: @test-add-mul-propagates859; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]860; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }861; CHECK-NEXT: %index32 = add nsw i32 %i, %offset862; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }863; CHECK-NEXT: %indexmul = mul nuw i32 %index32, 2864; CHECK-NEXT: --> {(2 * %offset),+,2}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (-2 + (2 * %offset) + (2 * %numIterations)) LoopDispositions: { %loop: Computable }865; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul866; CHECK-NEXT: --> ((4 * (sext i32 {(2 * %offset),+,2}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2 + (2 * %offset) + (2 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }867; CHECK-NEXT: %nexti = add nsw i32 %i, 1868; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }869; CHECK-NEXT: Determining loop execution counts for: @test-add-mul-propagates870; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)871; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1872; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)873; CHECK-NEXT: Loop %loop: Trip multiple is 1874;875entry:876 br label %loop877loop:878 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]879 880 %index32 = add nsw i32 %i, %offset881 882 %indexmul = mul nuw i32 %index32, 2883 %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul884 %nexti = add nsw i32 %i, 1885 %f = load float, ptr %ptr, align 4886 %exitcond = icmp eq i32 %nexti, %numIterations887 br i1 %exitcond, label %exit, label %loop888exit:889 ret void890}891 892; Any poison input to multiplication propages poison.893define void @test-mul-propagates-poison(ptr %input, i32 %offset, i32 %numIterations) {894; CHECK-LABEL: 'test-mul-propagates-poison'895; CHECK-NEXT: Classifying expressions for: @test-mul-propagates-poison896; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]897; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }898; CHECK-NEXT: %index32 = add nsw i32 %i, %offset899; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }900; CHECK-NEXT: %indexmul = mul nsw i32 %index32, %offset901; CHECK-NEXT: --> {(%offset * %offset),+,%offset}<%loop> U: full-set S: full-set Exits: ((-1 + %offset + %numIterations) * %offset) LoopDispositions: { %loop: Computable }902; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul903; CHECK-NEXT: --> ((4 * (sext i32 {(%offset * %offset),+,%offset}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 ((-1 + %offset + %numIterations) * %offset) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }904; CHECK-NEXT: %nexti = add nsw i32 %i, 1905; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }906; CHECK-NEXT: Determining loop execution counts for: @test-mul-propagates-poison907; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)908; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1909; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)910; CHECK-NEXT: Loop %loop: Trip multiple is 1911;912entry:913 br label %loop914loop:915 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]916 917 %index32 = add nsw i32 %i, %offset918 919 %indexmul = mul nsw i32 %index32, %offset920 %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul921 %nexti = add nsw i32 %i, 1922 %f = load float, ptr %ptr, align 4923 %exitcond = icmp eq i32 %nexti, %numIterations924 br i1 %exitcond, label %exit, label %loop925exit:926 ret void927}928 929define void @test-mul-propagates-poison-2(ptr %input, i32 %offset, i32 %numIterations) {930; CHECK-LABEL: 'test-mul-propagates-poison-2'931; CHECK-NEXT: Classifying expressions for: @test-mul-propagates-poison-2932; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]933; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }934; CHECK-NEXT: %index32 = add nsw i32 %i, %offset935; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }936; CHECK-NEXT: %indexmul = mul i32 %index32, 2937; CHECK-NEXT: --> {(2 * %offset),+,2}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (-2 + (2 * %offset) + (2 * %numIterations)) LoopDispositions: { %loop: Computable }938; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul939; CHECK-NEXT: --> ((4 * (sext i32 {(2 * %offset),+,2}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2 + (2 * %offset) + (2 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }940; CHECK-NEXT: %nexti = add nsw i32 %i, 1941; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }942; CHECK-NEXT: Determining loop execution counts for: @test-mul-propagates-poison-2943; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)944; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1945; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)946; CHECK-NEXT: Loop %loop: Trip multiple is 1947;948entry:949 br label %loop950loop:951 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]952 953 %index32 = add nsw i32 %i, %offset954 955 %indexmul = mul i32 %index32, 2956 %ptr = getelementptr inbounds float, ptr %input, i32 %indexmul957 %nexti = add nsw i32 %i, 1958 %f = load float, ptr %ptr, align 4959 %exitcond = icmp eq i32 %nexti, %numIterations960 br i1 %exitcond, label %exit, label %loop961exit:962 ret void963}964 965; Division by poison triggers UB.966define void @test-add-div(ptr %input, i32 %offset, i32 %numIterations) {967; CHECK-LABEL: 'test-add-div'968; CHECK-NEXT: Classifying expressions for: @test-add-div969; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]970; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }971; CHECK-NEXT: %j = add nsw i32 %i, %offset972; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }973; CHECK-NEXT: %q = sdiv i32 %numIterations, %j974; CHECK-NEXT: --> %q U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }975; CHECK-NEXT: %nexti = add nsw i32 %i, 1976; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }977; CHECK-NEXT: Determining loop execution counts for: @test-add-div978; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)979; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -1980; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)981; CHECK-NEXT: Loop %loop: Trip multiple is 1982;983entry:984 br label %loop985loop:986 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]987 988 %j = add nsw i32 %i, %offset989 990 %q = sdiv i32 %numIterations, %j991 %nexti = add nsw i32 %i, 1992 %exitcond = icmp eq i32 %nexti, %numIterations993 br i1 %exitcond, label %exit, label %loop994exit:995 ret void996}997 998; Remainder of poison by non-poison divisor does not trigger UB.999define void @test-add-div2(ptr %input, i32 %offset, i32 %numIterations) {1000; CHECK-LABEL: 'test-add-div2'1001; CHECK-NEXT: Classifying expressions for: @test-add-div21002; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1003; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1004; CHECK-NEXT: %j = add nsw i32 %i, %offset1005; CHECK-NEXT: --> {%offset,+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }1006; CHECK-NEXT: %q = sdiv i32 %j, %numIterations1007; CHECK-NEXT: --> %q U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }1008; CHECK-NEXT: %nexti = add nsw i32 %i, 11009; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1010; CHECK-NEXT: Determining loop execution counts for: @test-add-div21011; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1012; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11013; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1014; CHECK-NEXT: Loop %loop: Trip multiple is 11015;1016entry:1017 br label %loop1018loop:1019 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1020 1021 %j = add nsw i32 %i, %offset1022 1023 %q = sdiv i32 %j, %numIterations1024 %nexti = add nsw i32 %i, 11025 %exitcond = icmp eq i32 %nexti, %numIterations1026 br i1 %exitcond, label %exit, label %loop1027exit:1028 ret void1029}1030 1031; Store to poison address triggers UB.1032define void @test-add-store(ptr %input, i32 %offset, i32 %numIterations) {1033; CHECK-LABEL: 'test-add-store'1034; CHECK-NEXT: Classifying expressions for: @test-add-store1035; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1036; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1037; CHECK-NEXT: %index32 = add nsw i32 %i, %offset1038; CHECK-NEXT: --> {%offset,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }1039; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index321040; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1041; CHECK-NEXT: %nexti = add nsw i32 %i, 11042; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1043; CHECK-NEXT: Determining loop execution counts for: @test-add-store1044; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1045; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11046; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1047; CHECK-NEXT: Loop %loop: Trip multiple is 11048;1049entry:1050 br label %loop1051loop:1052 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1053 1054 %index32 = add nsw i32 %i, %offset1055 1056 %ptr = getelementptr inbounds float, ptr %input, i32 %index321057 %nexti = add nsw i32 %i, 11058 store float 1.0, ptr %ptr, align 41059 %exitcond = icmp eq i32 %nexti, %numIterations1060 br i1 %exitcond, label %exit, label %loop1061exit:1062 ret void1063}1064 1065; Three sequential adds where the middle add should have nsw. There is1066; a special case for sequential adds and this test covers that. We have to1067; put the final add first in the program since otherwise the special case1068; is not triggered, hence the strange basic block ordering.1069define void @test-add-twice(ptr %input, i32 %offset, i32 %numIterations) {1070; CHECK-LABEL: 'test-add-twice'1071; CHECK-NEXT: Classifying expressions for: @test-add-twice1072; CHECK-NEXT: %seq = add nuw nsw i32 %index32, 11073; CHECK-NEXT: --> {(2 + %offset),+,1}<nw><%loop> U: full-set S: full-set Exits: (1 + %offset + %numIterations) LoopDispositions: { %loop: Computable }1074; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]1075; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1076; CHECK-NEXT: %j = add nsw i32 %i, 11077; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1078; CHECK-NEXT: %index32 = add nsw i32 %j, %offset1079; CHECK-NEXT: --> {(1 + %offset)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable }1080; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index321081; CHECK-NEXT: --> {(4 + (4 * (sext i32 %offset to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %offset to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1082; CHECK-NEXT: %nexti = add nsw i32 %i, 11083; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1084; CHECK-NEXT: Determining loop execution counts for: @test-add-twice1085; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1086; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11087; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1088; CHECK-NEXT: Loop %loop: Trip multiple is 11089;1090entry:1091 br label %loop1092loop2:1093 %seq = add nsw nuw i32 %index32, 11094 %exitcond = icmp eq i32 %nexti, %numIterations1095 br i1 %exitcond, label %exit, label %loop1096 1097loop:1098 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]1099 1100 %j = add nsw i32 %i, 11101 %index32 = add nsw i32 %j, %offset1102 1103 %ptr = getelementptr inbounds float, ptr %input, i32 %index321104 %nexti = add nsw i32 %i, 11105 store float 1.0, ptr %ptr, align 41106 br label %loop21107exit:1108 ret void1109}1110 1111; Example where a mul should get the nsw flag, so that a sext can be1112; distributed over the mul.1113define void @test-mul-nsw(ptr %input, i32 %stride, i32 %numIterations) {1114; CHECK-LABEL: 'test-mul-nsw'1115; CHECK-NEXT: Classifying expressions for: @test-mul-nsw1116; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1117; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1118; CHECK-NEXT: %index32 = mul nsw i32 %i, %stride1119; CHECK-NEXT: --> {0,+,%stride}<nsw><%loop> U: full-set S: full-set Exits: ((-1 + %numIterations) * %stride) LoopDispositions: { %loop: Computable }1120; CHECK-NEXT: %index64 = sext i32 %index32 to i641121; CHECK-NEXT: --> {0,+,(sext i32 %stride to i64)}<nsw><%loop> U: [-9223372034707292160,9223372030412324866) S: [-9223372034707292160,9223372030412324866) Exits: ((zext i32 (-1 + %numIterations) to i64) * (sext i32 %stride to i64)) LoopDispositions: { %loop: Computable }1122; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641123; CHECK-NEXT: --> {%input,+,(4 * (sext i32 %stride to i64))<nsw>}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64) * (sext i32 %stride to i64)) + %input) LoopDispositions: { %loop: Computable }1124; CHECK-NEXT: %nexti = add nsw i32 %i, 11125; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1126; CHECK-NEXT: Determining loop execution counts for: @test-mul-nsw1127; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1128; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11129; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1130; CHECK-NEXT: Loop %loop: Trip multiple is 11131;1132entry:1133 br label %loop1134loop:1135 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1136 1137 %index32 = mul nsw i32 %i, %stride1138 1139 %index64 = sext i32 %index32 to i641140 1141 %ptr = getelementptr inbounds float, ptr %input, i64 %index641142 %nexti = add nsw i32 %i, 11143 %f = load float, ptr %ptr, align 41144 %exitcond = icmp eq i32 %nexti, %numIterations1145 br i1 %exitcond, label %exit, label %loop1146exit:1147 ret void1148}1149 1150; Example where a mul should get the nuw flag.1151define void @test-mul-nuw(ptr %input, i32 %stride, i32 %numIterations) {1152; CHECK-LABEL: 'test-mul-nuw'1153; CHECK-NEXT: Classifying expressions for: @test-mul-nuw1154; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1155; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1156; CHECK-NEXT: %index32 = mul nuw i32 %i, %stride1157; CHECK-NEXT: --> {0,+,%stride}<nuw><%loop> U: full-set S: full-set Exits: ((-1 + %numIterations) * %stride) LoopDispositions: { %loop: Computable }1158; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index321159; CHECK-NEXT: --> ((4 * (sext i32 {0,+,%stride}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 ((-1 + %numIterations) * %stride) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1160; CHECK-NEXT: %nexti = add nuw i32 %i, 11161; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }1162; CHECK-NEXT: Determining loop execution counts for: @test-mul-nuw1163; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1164; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11165; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1166; CHECK-NEXT: Loop %loop: Trip multiple is 11167;1168entry:1169 br label %loop1170loop:1171 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1172 1173 %index32 = mul nuw i32 %i, %stride1174 1175 %ptr = getelementptr inbounds float, ptr %input, i32 %index321176 %nexti = add nuw i32 %i, 11177 %f = load float, ptr %ptr, align 41178 %exitcond = icmp eq i32 %nexti, %numIterations1179 br i1 %exitcond, label %exit, label %loop1180 1181exit:1182 ret void1183}1184 1185; Example where a shl should get the nsw flag, so that a sext can be1186; distributed over the shl.1187define void @test-shl-nsw(ptr %input, i32 %start, i32 %numIterations) {1188; CHECK-LABEL: 'test-shl-nsw'1189; CHECK-NEXT: Classifying expressions for: @test-shl-nsw1190; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1191; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1192; CHECK-NEXT: %index32 = shl nsw i32 %i, 81193; CHECK-NEXT: --> {(256 * %start),+,256}<%loop> U: [0,-255) S: [-2147483648,2147483393) Exits: (-256 + (256 * %numIterations)) LoopDispositions: { %loop: Computable }1194; CHECK-NEXT: %index64 = sext i32 %index32 to i641195; CHECK-NEXT: --> (sext i32 {(256 * %start),+,256}<%loop> to i64) U: [0,-255) S: [-2147483648,2147483393) Exits: (sext i32 (-256 + (256 * %numIterations)) to i64) LoopDispositions: { %loop: Computable }1196; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641197; CHECK-NEXT: --> ((4 * (sext i32 {(256 * %start),+,256}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-256 + (256 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1198; CHECK-NEXT: %nexti = add nsw i32 %i, 11199; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1200; CHECK-NEXT: Determining loop execution counts for: @test-shl-nsw1201; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1202; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11203; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1204; CHECK-NEXT: Loop %loop: Trip multiple is 11205;1206entry:1207 br label %loop1208loop:1209 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1210 1211 %index32 = shl nsw i32 %i, 81212 1213 %index64 = sext i32 %index32 to i641214 1215 %ptr = getelementptr inbounds float, ptr %input, i64 %index641216 %nexti = add nsw i32 %i, 11217 %f = load float, ptr %ptr, align 41218 %exitcond = icmp eq i32 %nexti, %numIterations1219 br i1 %exitcond, label %exit, label %loop1220exit:1221 ret void1222}1223 1224; Example where a shl should get the nuw flag1225define void @test-shl-nuw-edgecase(ptr %input, i32 %start, i32 %numIterations) {1226; CHECK-LABEL: 'test-shl-nuw-edgecase'1227; CHECK-NEXT: Classifying expressions for: @test-shl-nuw-edgecase1228; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1229; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1230; CHECK-NEXT: %index32 = shl nuw i32 %i, 311231; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable }1232; CHECK-NEXT: %index64 = sext i32 %index32 to i641233; CHECK-NEXT: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64) U: [0,-2147483647) S: [-2147483648,1) Exits: (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64) LoopDispositions: { %loop: Computable }1234; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641235; CHECK-NEXT: --> ((4 * (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1236; CHECK-NEXT: %nexti = add nsw i32 %i, 11237; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1238; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw-edgecase1239; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1240; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11241; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1242; CHECK-NEXT: Loop %loop: Trip multiple is 11243;1244entry:1245 br label %loop1246loop:1247 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1248 1249 %index32 = shl nuw i32 %i, 311250 1251 %index64 = sext i32 %index32 to i641252 1253 %ptr = getelementptr inbounds float, ptr %input, i64 %index641254 %nexti = add nsw i32 %i, 11255 %f = load float, ptr %ptr, align 41256 %exitcond = icmp eq i32 %nexti, %numIterations1257 br i1 %exitcond, label %exit, label %loop1258exit:1259 ret void1260}1261 1262; Example where a shl should get the nuw flag1263define void @test-shl-nuw-nsw(ptr %input, i32 %start, i32 %numIterations) {1264; CHECK-LABEL: 'test-shl-nuw-nsw'1265; CHECK-NEXT: Classifying expressions for: @test-shl-nuw-nsw1266; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1267; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1268; CHECK-NEXT: %index32 = shl nuw nsw i32 %i, 311269; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable }1270; CHECK-NEXT: %index64 = sext i32 %index32 to i641271; CHECK-NEXT: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64) U: [0,-2147483647) S: [-2147483648,1) Exits: (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64) LoopDispositions: { %loop: Computable }1272; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641273; CHECK-NEXT: --> ((4 * (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1274; CHECK-NEXT: %nexti = add nsw i32 %i, 11275; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1276; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw-nsw1277; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1278; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11279; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1280; CHECK-NEXT: Loop %loop: Trip multiple is 11281;1282entry:1283 br label %loop1284loop:1285 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1286 1287 %index32 = shl nuw nsw i32 %i, 311288 1289 %index64 = sext i32 %index32 to i641290 1291 %ptr = getelementptr inbounds float, ptr %input, i64 %index641292 %nexti = add nsw i32 %i, 11293 %f = load float, ptr %ptr, align 41294 %exitcond = icmp eq i32 %nexti, %numIterations1295 br i1 %exitcond, label %exit, label %loop1296exit:1297 ret void1298}1299 1300; Example where a shl should not get the nsw flag1301define void @test-shl-no-nsw(ptr %input, i32 %start, i32 %numIterations) {1302; CHECK-LABEL: 'test-shl-no-nsw'1303; CHECK-NEXT: Classifying expressions for: @test-shl-no-nsw1304; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1305; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1306; CHECK-NEXT: %index32 = shl nsw i32 %i, 311307; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable }1308; CHECK-NEXT: %index64 = sext i32 %index32 to i641309; CHECK-NEXT: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64) U: [0,-2147483647) S: [-2147483648,1) Exits: (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64) LoopDispositions: { %loop: Computable }1310; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641311; CHECK-NEXT: --> ((4 * (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1312; CHECK-NEXT: %nexti = add nsw i32 %i, 11313; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1314; CHECK-NEXT: Determining loop execution counts for: @test-shl-no-nsw1315; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1316; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11317; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1318; CHECK-NEXT: Loop %loop: Trip multiple is 11319;1320entry:1321 br label %loop1322loop:1323 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1324 1325 %index32 = shl nsw i32 %i, 311326 1327 %index64 = sext i32 %index32 to i641328 1329 %ptr = getelementptr inbounds float, ptr %input, i64 %index641330 %nexti = add nsw i32 %i, 11331 %f = load float, ptr %ptr, align 41332 %exitcond = icmp eq i32 %nexti, %numIterations1333 br i1 %exitcond, label %exit, label %loop1334exit:1335 ret void1336}1337 1338; Example where a shl should get the nsw flag.1339define void @test-shl-nsw-edgecase(ptr %input, i32 %start, i32 %numIterations) {1340; CHECK-LABEL: 'test-shl-nsw-edgecase'1341; CHECK-NEXT: Classifying expressions for: @test-shl-nsw-edgecase1342; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1343; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1344; CHECK-NEXT: %index32 = shl nsw i32 %i, 301345; CHECK-NEXT: --> {(1073741824 * %start),+,1073741824}<%loop> U: [0,-1073741823) S: [-2147483648,1073741825) Exits: (-1073741824 + (1073741824 * %numIterations)) LoopDispositions: { %loop: Computable }1346; CHECK-NEXT: %index64 = sext i32 %index32 to i641347; CHECK-NEXT: --> (sext i32 {(1073741824 * %start),+,1073741824}<%loop> to i64) U: [0,-1073741823) S: [-2147483648,1073741825) Exits: (sext i32 (-1073741824 + (1073741824 * %numIterations)) to i64) LoopDispositions: { %loop: Computable }1348; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641349; CHECK-NEXT: --> ((4 * (sext i32 {(1073741824 * %start),+,1073741824}<%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1073741824 + (1073741824 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1350; CHECK-NEXT: %nexti = add nsw i32 %i, 11351; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1352; CHECK-NEXT: Determining loop execution counts for: @test-shl-nsw-edgecase1353; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1354; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11355; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1356; CHECK-NEXT: Loop %loop: Trip multiple is 11357;1358entry:1359 br label %loop1360loop:1361 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1362 1363 %index32 = shl nsw i32 %i, 301364 1365 %index64 = sext i32 %index32 to i641366 1367 %ptr = getelementptr inbounds float, ptr %input, i64 %index641368 %nexti = add nsw i32 %i, 11369 %f = load float, ptr %ptr, align 41370 %exitcond = icmp eq i32 %nexti, %numIterations1371 br i1 %exitcond, label %exit, label %loop1372exit:1373 ret void1374}1375 1376; Example where a shl should get the nuw flag.1377define void @test-shl-nuw(ptr %input, i32 %numIterations) {1378; CHECK-LABEL: 'test-shl-nuw'1379; CHECK-NEXT: Classifying expressions for: @test-shl-nuw1380; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1381; CHECK-NEXT: --> {0,+,1}<nuw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1382; CHECK-NEXT: %index32 = shl nuw i32 %i, 91383; CHECK-NEXT: --> {0,+,512}<nuw><%loop> U: [0,-511) S: [-2147483648,2147483137) Exits: (-512 + (512 * %numIterations)) LoopDispositions: { %loop: Computable }1384; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index321385; CHECK-NEXT: --> ((4 * (sext i32 {0,+,512}<nuw><%loop> to i64))<nsw> + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-512 + (512 * %numIterations)) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1386; CHECK-NEXT: %nexti = add nuw i32 %i, 11387; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable }1388; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw1389; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1390; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11391; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1392; CHECK-NEXT: Loop %loop: Trip multiple is 11393;1394entry:1395 br label %loop1396loop:1397 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1398 1399 %index32 = shl nuw i32 %i, 91400 1401 %ptr = getelementptr inbounds float, ptr %input, i32 %index321402 %nexti = add nuw i32 %i, 11403 %f = load float, ptr %ptr, align 41404 %exitcond = icmp eq i32 %nexti, %numIterations1405 br i1 %exitcond, label %exit, label %loop1406 1407exit:1408 ret void1409}1410 1411; Example where a sub should *not* get the nsw flag, because of how1412; scalar evolution represents A - B as A + (-B) and -B can wrap even1413; in cases where A - B does not.1414define void @test-sub-no-nsw(ptr %input, i32 %start, i32 %sub, i32 %numIterations) {1415; CHECK-LABEL: 'test-sub-no-nsw'1416; CHECK-NEXT: Classifying expressions for: @test-sub-no-nsw1417; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1418; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1419; CHECK-NEXT: %index32 = sub nsw i32 %i, %sub1420; CHECK-NEXT: --> {((-1 * %sub) + %start),+,1}<nw><%loop> U: full-set S: full-set Exits: (-1 + (-1 * %sub) + %numIterations) LoopDispositions: { %loop: Computable }1421; CHECK-NEXT: %index64 = sext i32 %index32 to i641422; CHECK-NEXT: --> {((sext i32 %start to i64) + (-1 * (sext i32 %sub to i64))<nsw>)<nsw>,+,1}<nsw><%loop> U: [-4294967295,8589934591) S: [-4294967295,8589934591) Exits: ((zext i32 (-1 + (-1 * %start) + %numIterations) to i64) + (sext i32 %start to i64) + (-1 * (sext i32 %sub to i64))<nsw>) LoopDispositions: { %loop: Computable }1423; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641424; CHECK-NEXT: --> {((4 * (sext i32 %start to i64))<nsw> + (-4 * (sext i32 %sub to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %start to i64))<nsw> + (-4 * (sext i32 %sub to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1425; CHECK-NEXT: %nexti = add nsw i32 %i, 11426; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1427; CHECK-NEXT: Determining loop execution counts for: @test-sub-no-nsw1428; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1429; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11430; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1431; CHECK-NEXT: Loop %loop: Trip multiple is 11432;1433entry:1434 br label %loop1435loop:1436 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1437 1438 %index32 = sub nsw i32 %i, %sub1439 %index64 = sext i32 %index32 to i641440 1441 %ptr = getelementptr inbounds float, ptr %input, i64 %index641442 %nexti = add nsw i32 %i, 11443 %f = load float, ptr %ptr, align 41444 %exitcond = icmp eq i32 %nexti, %numIterations1445 br i1 %exitcond, label %exit, label %loop1446exit:1447 ret void1448}1449 1450; Example where a sub should get the nsw flag as the RHS cannot be the1451; minimal signed value.1452define void @test-sub-nsw(ptr %input, i32 %start, i32 %sub, i32 %numIterations) {1453; CHECK-LABEL: 'test-sub-nsw'1454; CHECK-NEXT: Classifying expressions for: @test-sub-nsw1455; CHECK-NEXT: %halfsub = ashr i32 %sub, 11456; CHECK-NEXT: --> %halfsub U: [-1073741824,1073741824) S: [-1073741824,1073741824)1457; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1458; CHECK-NEXT: --> {%start,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1459; CHECK-NEXT: %index32 = sub nsw i32 %i, %halfsub1460; CHECK-NEXT: --> {((-1 * %halfsub)<nsw> + %start)<nsw>,+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + (-1 * %halfsub)<nsw> + %numIterations) LoopDispositions: { %loop: Computable }1461; CHECK-NEXT: %index64 = sext i32 %index32 to i641462; CHECK-NEXT: --> {((sext i32 %start to i64) + (-1 * (sext i32 %halfsub to i64))<nsw>)<nsw>,+,1}<nsw><%loop> U: [-3221225471,7516192767) S: [-3221225471,7516192767) Exits: ((zext i32 (-1 + (-1 * %start) + %numIterations) to i64) + (sext i32 %start to i64) + (-1 * (sext i32 %halfsub to i64))<nsw>) LoopDispositions: { %loop: Computable }1463; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641464; CHECK-NEXT: --> {((4 * (sext i32 %start to i64))<nsw> + (-4 * (sext i32 %halfsub to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 %start to i64))<nsw> + (-4 * (sext i32 %halfsub to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1465; CHECK-NEXT: %nexti = add nsw i32 %i, 11466; CHECK-NEXT: --> {(1 + %start)<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1467; CHECK-NEXT: Determining loop execution counts for: @test-sub-nsw1468; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations)1469; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11470; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + (-1 * %start) + %numIterations)1471; CHECK-NEXT: Loop %loop: Trip multiple is 11472;1473entry:1474 %halfsub = ashr i32 %sub, 11475 br label %loop1476loop:1477 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ]1478 1479 %index32 = sub nsw i32 %i, %halfsub1480 %index64 = sext i32 %index32 to i641481 1482 %ptr = getelementptr inbounds float, ptr %input, i64 %index641483 %nexti = add nsw i32 %i, 11484 %f = load float, ptr %ptr, align 41485 %exitcond = icmp eq i32 %nexti, %numIterations1486 br i1 %exitcond, label %exit, label %loop1487exit:1488 ret void1489}1490 1491; Example where a sub should get the nsw flag, since the LHS is non-negative,1492; which implies that the RHS cannot be the minimal signed value.1493define void @test-sub-nsw-lhs-non-negative(ptr %input, i32 %sub, i32 %numIterations) {1494; CHECK-LABEL: 'test-sub-nsw-lhs-non-negative'1495; CHECK-NEXT: Classifying expressions for: @test-sub-nsw-lhs-non-negative1496; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1497; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1498; CHECK-NEXT: %index32 = sub nsw i32 %i, %sub1499; CHECK-NEXT: --> {(-1 * %sub),+,1}<nsw><%loop> U: full-set S: full-set Exits: (-1 + (-1 * %sub) + %numIterations) LoopDispositions: { %loop: Computable }1500; CHECK-NEXT: %index64 = sext i32 %index32 to i641501; CHECK-NEXT: --> {(-1 * (sext i32 %sub to i64))<nsw>,+,1}<nsw><%loop> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: ((zext i32 (-1 + %numIterations) to i64) + (-1 * (sext i32 %sub to i64))<nsw>) LoopDispositions: { %loop: Computable }1502; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641503; CHECK-NEXT: --> {((-4 * (sext i32 %sub to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (-4 * (sext i32 %sub to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1504; CHECK-NEXT: %nexti = add nsw i32 %i, 11505; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1506; CHECK-NEXT: Determining loop execution counts for: @test-sub-nsw-lhs-non-negative1507; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1508; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11509; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1510; CHECK-NEXT: Loop %loop: Trip multiple is 11511;1512entry:1513 br label %loop1514loop:1515 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ]1516 1517 %index32 = sub nsw i32 %i, %sub1518 1519 %index64 = sext i32 %index32 to i641520 1521 %ptr = getelementptr inbounds float, ptr %input, i64 %index641522 %nexti = add nsw i32 %i, 11523 %f = load float, ptr %ptr, align 41524 %exitcond = icmp eq i32 %nexti, %numIterations1525 br i1 %exitcond, label %exit, label %loop1526exit:1527 ret void1528}1529 1530; Example checking that a sext is pushed onto a sub's operands if the sub is an1531; overflow intrinsic.1532define void @test-sext-sub(ptr %input, i32 %sub, i32 %numIterations) {1533; CHECK-LABEL: 'test-sext-sub'1534; CHECK-NEXT: Classifying expressions for: @test-sext-sub1535; CHECK-NEXT: %i = phi i32 [ %nexti, %cont ], [ 0, %entry ]1536; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }1537; CHECK-NEXT: %val = extractvalue { i32, i1 } %ssub, 01538; CHECK-NEXT: --> {(-1 * %sub),+,1}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }1539; CHECK-NEXT: %ovfl = extractvalue { i32, i1 } %ssub, 11540; CHECK-NEXT: --> %ovfl U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Variant }1541; CHECK-NEXT: %index64 = sext i32 %val to i641542; CHECK-NEXT: --> {(-1 * (sext i32 %sub to i64))<nsw>,+,1}<nsw><%loop> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }1543; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i64 %index641544; CHECK-NEXT: --> {((-4 * (sext i32 %sub to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }1545; CHECK-NEXT: %nexti = add nsw i32 %i, 11546; CHECK-NEXT: --> {1,+,1}<nuw><%loop> U: [1,0) S: [1,0) Exits: <<Unknown>> LoopDispositions: { %loop: Computable }1547; CHECK-NEXT: Determining loop execution counts for: @test-sext-sub1548; CHECK-NEXT: Loop %loop: <multiple exits> Unpredictable backedge-taken count.1549; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE***1550; CHECK-NEXT: exit count for cont: (-1 + %numIterations)1551; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11552; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1553; CHECK-NEXT: symbolic max exit count for loop: ***COULDNOTCOMPUTE***1554; CHECK-NEXT: symbolic max exit count for cont: (-1 + %numIterations)1555;1556entry:1557 br label %loop1558loop:1559 %i = phi i32 [ %nexti, %cont ], [ 0, %entry ]1560 1561 %ssub = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i, i32 %sub)1562 %val = extractvalue { i32, i1 } %ssub, 01563 %ovfl = extractvalue { i32, i1 } %ssub, 11564 br i1 %ovfl, label %trap, label %cont1565 1566trap:1567 tail call void @llvm.trap()1568 unreachable1569 1570cont:1571 %index64 = sext i32 %val to i641572 1573 %ptr = getelementptr inbounds float, ptr %input, i64 %index641574 %nexti = add nsw i32 %i, 11575 %f = load float, ptr %ptr, align 41576 %exitcond = icmp eq i32 %nexti, %numIterations1577 br i1 %exitcond, label %exit, label %loop1578exit:1579 ret void1580}1581 1582; Two adds with a sub in the middle and the sub should have nsw. There is1583; a special case for sequential adds/subs and this test covers that. We have to1584; put the final add first in the program since otherwise the special case1585; is not triggered, hence the strange basic block ordering.1586define void @test-sub-with-add(ptr %input, i32 %offset, i32 %numIterations) {1587; CHECK-LABEL: 'test-sub-with-add'1588; CHECK-NEXT: Classifying expressions for: @test-sub-with-add1589; CHECK-NEXT: %seq = add nuw nsw i32 %index32, 11590; CHECK-NEXT: --> {(2 + (-1 * %offset)),+,1}<nw><%loop> U: full-set S: full-set Exits: (1 + (-1 * %offset) + %numIterations) LoopDispositions: { %loop: Computable }1591; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]1592; CHECK-NEXT: --> {0,+,1}<nuw><nsw><%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable }1593; CHECK-NEXT: %j = add nsw i32 %i, 11594; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1595; CHECK-NEXT: %index32 = sub nsw i32 %j, %offset1596; CHECK-NEXT: --> {(1 + (-1 * %offset))<nsw>,+,1}<nsw><%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: ((-1 * %offset) + %numIterations) LoopDispositions: { %loop: Computable }1597; CHECK-NEXT: %ptr = getelementptr inbounds float, ptr %input, i32 %index321598; CHECK-NEXT: --> {(4 + (4 * (sext i32 (-1 * %offset) to i64))<nsw> + %input),+,4}<nw><%loop> U: full-set S: full-set Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64))<nuw><nsw> + (4 * (sext i32 (-1 * %offset) to i64))<nsw> + %input) LoopDispositions: { %loop: Computable }1599; CHECK-NEXT: %nexti = add nsw i32 %i, 11600; CHECK-NEXT: --> {1,+,1}<nuw><nsw><%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable }1601; CHECK-NEXT: Determining loop execution counts for: @test-sub-with-add1602; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations)1603; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i32 -11604; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is (-1 + %numIterations)1605; CHECK-NEXT: Loop %loop: Trip multiple is 11606;1607entry:1608 br label %loop1609loop2:1610 %seq = add nsw nuw i32 %index32, 11611 %exitcond = icmp eq i32 %nexti, %numIterations1612 br i1 %exitcond, label %exit, label %loop1613 1614loop:1615 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ]1616 1617 %j = add nsw i32 %i, 11618 %index32 = sub nsw i32 %j, %offset1619 1620 %ptr = getelementptr inbounds float, ptr %input, i32 %index321621 %nexti = add nsw i32 %i, 11622 store float 1.0, ptr %ptr, align 41623 br label %loop21624exit:1625 ret void1626}1627 1628; PR28932: Don't assert on non-SCEV-able value %2.1629%struct.anon = type { ptr }1630@a = common global ptr null, align 81631@b = common global i32 0, align 41632declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)1633declare void @llvm.trap()1634define i32 @pr28932() {1635; CHECK-LABEL: 'pr28932'1636; CHECK-NEXT: Classifying expressions for: @pr289321637; CHECK-NEXT: %pre = load ptr, ptr @a, align 81638; CHECK-NEXT: --> %pre U: full-set S: full-set1639; CHECK-NEXT: %pre7 = load i32, ptr @b, align 41640; CHECK-NEXT: --> %pre7 U: full-set S: full-set1641; CHECK-NEXT: %i = phi i32 [ %i3, %cont6 ], [ %pre7, %entry ]1642; CHECK-NEXT: --> {%pre7,+,-1}<%for.cond> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }1643; CHECK-NEXT: %i1 = phi ptr [ %ph, %cont6 ], [ %pre, %entry ]1644; CHECK-NEXT: --> %i1 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1645; CHECK-NEXT: %i3 = extractvalue { i32, i1 } %i2, 01646; CHECK-NEXT: --> {(-1 + %pre7),+,-1}<%for.cond> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }1647; CHECK-NEXT: %i4 = extractvalue { i32, i1 } %i2, 11648; CHECK-NEXT: --> %i4 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1649; CHECK-NEXT: %idxprom = sext i32 %i3 to i641650; CHECK-NEXT: --> (sext i32 {(-1 + %pre7),+,-1}<%for.cond> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <<Unknown>> LoopDispositions: { %for.cond: Computable }1651; CHECK-NEXT: %i6 = load ptr, ptr %i1, align 81652; CHECK-NEXT: --> %i6 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1653; CHECK-NEXT: %i7 = getelementptr inbounds i8, ptr %i6, i64 %idxprom1654; CHECK-NEXT: --> ((sext i32 {(-1 + %pre7),+,-1}<%for.cond> to i64) + %i6) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1655; CHECK-NEXT: %i8 = load i8, ptr %i7, align 11656; CHECK-NEXT: --> %i8 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1657; CHECK-NEXT: %conv5 = sext i8 %i8 to i641658; CHECK-NEXT: --> (sext i8 %i8 to i64) U: [-128,128) S: [-128,128) Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1659; CHECK-NEXT: %i9 = inttoptr i64 %conv5 to ptr1660; CHECK-NEXT: --> %i9 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1661; CHECK-NEXT: %ph = phi ptr [ %i9, %cont1 ], [ %i1, %if.then ]1662; CHECK-NEXT: --> %ph U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %for.cond: Variant }1663; CHECK-NEXT: Determining loop execution counts for: @pr289321664; CHECK-NEXT: Loop %for.cond: <multiple exits> Unpredictable backedge-taken count.1665; CHECK-NEXT: exit count for if.then: ***COULDNOTCOMPUTE***1666; CHECK-NEXT: exit count for if.else: ***COULDNOTCOMPUTE***1667; CHECK-NEXT: Loop %for.cond: Unpredictable constant max backedge-taken count.1668; CHECK-NEXT: Loop %for.cond: Unpredictable symbolic max backedge-taken count.1669; CHECK-NEXT: symbolic max exit count for if.then: ***COULDNOTCOMPUTE***1670; CHECK-NEXT: symbolic max exit count for if.else: ***COULDNOTCOMPUTE***1671;1672entry:1673 %pre = load ptr, ptr @a, align 81674 %pre7 = load i32, ptr @b, align 41675 br label %for.cond1676 1677for.cond: ; preds = %cont6, %entry1678 %i = phi i32 [ %i3, %cont6 ], [ %pre7, %entry ]1679 %i1 = phi ptr [ %ph, %cont6 ], [ %pre, %entry ]1680 %tobool = icmp eq ptr %i1, null1681 %i2 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i, i32 1)1682 %i3 = extractvalue { i32, i1 } %i2, 01683 %i4 = extractvalue { i32, i1 } %i2, 11684 %idxprom = sext i32 %i3 to i641685 %i6 = load ptr, ptr %i1, align 81686 %i7 = getelementptr inbounds i8, ptr %i6, i64 %idxprom1687 %i8 = load i8, ptr %i7, align 11688 br i1 %tobool, label %if.else, label %if.then1689 1690if.then: ; preds = %for.cond1691 br i1 %i4, label %trap, label %cont61692 1693trap: ; preds = %if.else, %if.then1694 tail call void @llvm.trap()1695 unreachable1696 1697if.else: ; preds = %for.cond1698 br i1 %i4, label %trap, label %cont11699 1700cont1: ; preds = %if.else1701 %conv5 = sext i8 %i8 to i641702 %i9 = inttoptr i64 %conv5 to ptr1703 store ptr %i9, ptr @a, align 81704 br label %cont61705 1706cont6: ; preds = %cont1, %if.then1707 %ph = phi ptr [ %i9, %cont1 ], [ %i1, %if.then ]1708 store i32 %i3, ptr @b, align 41709 br label %for.cond1710}1711 1712define noundef i32 @add-basic(i32 %a, i32 %b) {1713; CHECK-LABEL: 'add-basic'1714; CHECK-NEXT: Classifying expressions for: @add-basic1715; CHECK-NEXT: %res = add nuw nsw i32 %a, %b1716; CHECK-NEXT: --> (%a + %b)<nuw><nsw> U: full-set S: full-set1717; CHECK-NEXT: Determining loop execution counts for: @add-basic1718;1719 %res = add nuw nsw i32 %a, %b1720 ret i32 %res1721}1722 1723define noundef i32 @sub-basic(i32 %a, i32 %b) {1724; CHECK-LABEL: 'sub-basic'1725; CHECK-NEXT: Classifying expressions for: @sub-basic1726; CHECK-NEXT: %res = sub nuw nsw i32 %a, %b1727; CHECK-NEXT: --> ((-1 * %b) + %a) U: full-set S: full-set1728; CHECK-NEXT: Determining loop execution counts for: @sub-basic1729;1730 %res = sub nuw nsw i32 %a, %b1731 ret i32 %res1732}1733 1734define noundef i32 @mul-basic(i32 %a, i32 %b) {1735; CHECK-LABEL: 'mul-basic'1736; CHECK-NEXT: Classifying expressions for: @mul-basic1737; CHECK-NEXT: %res = mul nuw nsw i32 %a, %b1738; CHECK-NEXT: --> (%a * %b)<nuw><nsw> U: full-set S: full-set1739; CHECK-NEXT: Determining loop execution counts for: @mul-basic1740;1741 %res = mul nuw nsw i32 %a, %b1742 ret i32 %res1743}1744 1745define noundef i32 @udiv-basic(i32 %a, i32 %b) {1746; CHECK-LABEL: 'udiv-basic'1747; CHECK-NEXT: Classifying expressions for: @udiv-basic1748; CHECK-NEXT: %res = udiv exact i32 %a, %b1749; CHECK-NEXT: --> (%a /u %b) U: full-set S: full-set1750; CHECK-NEXT: Determining loop execution counts for: @udiv-basic1751;1752 %res = udiv exact i32 %a, %b1753 ret i32 %res1754}1755 1756@gA = external global i321757@gB = external global i321758@gC = external global i321759@gD = external global i321760 1761define noundef i64 @add-zext-recurse(i64 %arg) {1762; CHECK-LABEL: 'add-zext-recurse'1763; CHECK-NEXT: Classifying expressions for: @add-zext-recurse1764; CHECK-NEXT: %a = load i32, ptr @gA, align 41765; CHECK-NEXT: --> %a U: full-set S: full-set1766; CHECK-NEXT: %x = zext i32 %a to i641767; CHECK-NEXT: --> (zext i32 %a to i64) U: [0,4294967296) S: [0,4294967296)1768; CHECK-NEXT: %res = add nuw i64 %x, %arg1769; CHECK-NEXT: --> ((zext i32 %a to i64) + %arg)<nuw> U: full-set S: full-set1770; CHECK-NEXT: Determining loop execution counts for: @add-zext-recurse1771;1772 call void @foo()1773 %a = load i32, ptr @gA1774 %x = zext i32 %a to i641775 %res = add nuw i64 %x, %arg1776 ret i64 %res1777}1778 1779define noundef i64 @add-sext-recurse(i64 %arg) {1780; CHECK-LABEL: 'add-sext-recurse'1781; CHECK-NEXT: Classifying expressions for: @add-sext-recurse1782; CHECK-NEXT: %a = load i32, ptr @gA, align 41783; CHECK-NEXT: --> %a U: full-set S: full-set1784; CHECK-NEXT: %x = sext i32 %a to i641785; CHECK-NEXT: --> (sext i32 %a to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648)1786; CHECK-NEXT: %res = add nuw i64 %x, %arg1787; CHECK-NEXT: --> ((sext i32 %a to i64) + %arg)<nuw> U: full-set S: full-set1788; CHECK-NEXT: Determining loop execution counts for: @add-sext-recurse1789;1790 call void @foo()1791 %a = load i32, ptr @gA1792 %x = sext i32 %a to i641793 %res = add nuw i64 %x, %arg1794 ret i64 %res1795}1796 1797define noundef i16 @add-trunc-recurse() {1798; CHECK-LABEL: 'add-trunc-recurse'1799; CHECK-NEXT: Classifying expressions for: @add-trunc-recurse1800; CHECK-NEXT: %a = load i32, ptr @gA, align 41801; CHECK-NEXT: --> %a U: full-set S: full-set1802; CHECK-NEXT: %x = trunc i32 %a to i161803; CHECK-NEXT: --> (trunc i32 %a to i16) U: full-set S: full-set1804; CHECK-NEXT: %res = add nuw i16 %x, 11805; CHECK-NEXT: --> (1 + (trunc i32 %a to i16))<nuw> U: [1,0) S: [1,0)1806; CHECK-NEXT: Determining loop execution counts for: @add-trunc-recurse1807;1808 call void @foo()1809 %a = load i32, ptr @gA1810 %x = trunc i32 %a to i161811 %res = add nuw i16 %x, 11812 ret i16 %res1813}1814 1815define noundef i32 @add-udiv-recurse(i32 %arg) {1816; CHECK-LABEL: 'add-udiv-recurse'1817; CHECK-NEXT: Classifying expressions for: @add-udiv-recurse1818; CHECK-NEXT: %a = load i32, ptr @gA, align 41819; CHECK-NEXT: --> %a U: full-set S: full-set1820; CHECK-NEXT: %x = udiv i32 %a, %arg1821; CHECK-NEXT: --> (%a /u %arg) U: full-set S: full-set1822; CHECK-NEXT: %res = add nuw i32 %x, 11823; CHECK-NEXT: --> (1 + (%a /u %arg))<nuw> U: [1,0) S: [1,0)1824; CHECK-NEXT: Determining loop execution counts for: @add-udiv-recurse1825;1826 call void @foo()1827 %a = load i32, ptr @gA1828 %x = udiv i32 %a, %arg1829 %res = add nuw i32 %x, 11830 ret i32 %res1831}1832 1833define noundef i32 @add-mul-recurse() {1834; CHECK-LABEL: 'add-mul-recurse'1835; CHECK-NEXT: Classifying expressions for: @add-mul-recurse1836; CHECK-NEXT: %a = load i32, ptr @gA, align 41837; CHECK-NEXT: --> %a U: full-set S: full-set1838; CHECK-NEXT: %x = mul i32 %a, 31839; CHECK-NEXT: --> (3 * %a) U: full-set S: full-set1840; CHECK-NEXT: %res = add nuw i32 %x, 11841; CHECK-NEXT: --> (1 + (3 * %a))<nuw> U: [1,0) S: [1,0)1842; CHECK-NEXT: Determining loop execution counts for: @add-mul-recurse1843;1844 call void @foo()1845 %a = load i32, ptr @gA1846 %x = mul i32 %a, 31847 %res = add nuw i32 %x, 11848 ret i32 %res1849}1850 1851declare i32 @llvm.smin.i32(i32, i32)1852declare i32 @llvm.smax.i32(i32, i32)1853declare i32 @llvm.umin.i32(i32, i32)1854declare i32 @llvm.umax.i32(i32, i32)1855 1856define noundef i32 @add-smin-recurse(i32 %arg) {1857; CHECK-LABEL: 'add-smin-recurse'1858; CHECK-NEXT: Classifying expressions for: @add-smin-recurse1859; CHECK-NEXT: %a = load i32, ptr @gA, align 41860; CHECK-NEXT: --> %a U: full-set S: full-set1861; CHECK-NEXT: %x = call i32 @llvm.smin.i32(i32 %a, i32 %arg)1862; CHECK-NEXT: --> (%arg smin %a) U: full-set S: full-set1863; CHECK-NEXT: %res = add nuw i32 %x, 11864; CHECK-NEXT: --> (1 + (%arg smin %a))<nuw> U: [1,0) S: [1,0)1865; CHECK-NEXT: Determining loop execution counts for: @add-smin-recurse1866;1867 call void @foo()1868 %a = load i32, ptr @gA1869 %x = call i32 @llvm.smin.i32(i32 %a, i32 %arg)1870 %res = add nuw i32 %x, 11871 ret i32 %res1872}1873 1874define noundef i32 @add-smax-recurse(i32 %arg) {1875; CHECK-LABEL: 'add-smax-recurse'1876; CHECK-NEXT: Classifying expressions for: @add-smax-recurse1877; CHECK-NEXT: %a = load i32, ptr @gA, align 41878; CHECK-NEXT: --> %a U: full-set S: full-set1879; CHECK-NEXT: %x = call i32 @llvm.smax.i32(i32 %a, i32 %arg)1880; CHECK-NEXT: --> (%arg smax %a) U: full-set S: full-set1881; CHECK-NEXT: %res = add nuw i32 %x, 11882; CHECK-NEXT: --> (1 + (%arg smax %a))<nuw> U: [1,0) S: [1,0)1883; CHECK-NEXT: Determining loop execution counts for: @add-smax-recurse1884;1885 call void @foo()1886 %a = load i32, ptr @gA1887 %x = call i32 @llvm.smax.i32(i32 %a, i32 %arg)1888 %res = add nuw i32 %x, 11889 ret i32 %res1890}1891 1892define noundef i32 @add-umin-recurse(i32 %arg) {1893; CHECK-LABEL: 'add-umin-recurse'1894; CHECK-NEXT: Classifying expressions for: @add-umin-recurse1895; CHECK-NEXT: %a = load i32, ptr @gA, align 41896; CHECK-NEXT: --> %a U: full-set S: full-set1897; CHECK-NEXT: %x = call i32 @llvm.umin.i32(i32 %a, i32 %arg)1898; CHECK-NEXT: --> (%arg umin %a) U: full-set S: full-set1899; CHECK-NEXT: %res = add nuw i32 %x, 11900; CHECK-NEXT: --> (1 + (%arg umin %a))<nuw> U: [1,0) S: [1,0)1901; CHECK-NEXT: Determining loop execution counts for: @add-umin-recurse1902;1903 call void @foo()1904 %a = load i32, ptr @gA1905 %x = call i32 @llvm.umin.i32(i32 %a, i32 %arg)1906 %res = add nuw i32 %x, 11907 ret i32 %res1908}1909 1910define noundef i32 @add-umax-recurse(i32 %arg) {1911; CHECK-LABEL: 'add-umax-recurse'1912; CHECK-NEXT: Classifying expressions for: @add-umax-recurse1913; CHECK-NEXT: %a = load i32, ptr @gA, align 41914; CHECK-NEXT: --> %a U: full-set S: full-set1915; CHECK-NEXT: %x = call i32 @llvm.umax.i32(i32 %a, i32 %arg)1916; CHECK-NEXT: --> (%arg umax %a) U: full-set S: full-set1917; CHECK-NEXT: %res = add nuw i32 %x, 11918; CHECK-NEXT: --> (1 + (%arg umax %a))<nuw> U: [1,0) S: [1,0)1919; CHECK-NEXT: Determining loop execution counts for: @add-umax-recurse1920;1921 call void @foo()1922 %a = load i32, ptr @gA1923 %x = call i32 @llvm.umax.i32(i32 %a, i32 %arg)1924 %res = add nuw i32 %x, 11925 ret i32 %res1926}1927 1928 1929define noundef i32 @add-recurse-inline() {1930; CHECK-LABEL: 'add-recurse-inline'1931; CHECK-NEXT: Classifying expressions for: @add-recurse-inline1932; CHECK-NEXT: %a = load i32, ptr @gA, align 41933; CHECK-NEXT: --> %a U: full-set S: full-set1934; CHECK-NEXT: %b = load i32, ptr @gB, align 41935; CHECK-NEXT: --> %b U: full-set S: full-set1936; CHECK-NEXT: %c = load i32, ptr @gC, align 41937; CHECK-NEXT: --> %c U: full-set S: full-set1938; CHECK-NEXT: %d = load i32, ptr @gD, align 41939; CHECK-NEXT: --> %d U: full-set S: full-set1940; CHECK-NEXT: %x = add nuw i32 %a, %b1941; CHECK-NEXT: --> (%a + %b)<nuw> U: full-set S: full-set1942; CHECK-NEXT: %y = add nuw i32 %c, %d1943; CHECK-NEXT: --> (%c + %d)<nuw> U: full-set S: full-set1944; CHECK-NEXT: %res = add nuw i32 %x, %y1945; CHECK-NEXT: --> (%a + %b + %c + %d)<nuw> U: full-set S: full-set1946; CHECK-NEXT: Determining loop execution counts for: @add-recurse-inline1947;1948 call void @foo()1949 %a = load i32, ptr @gA1950 %b = load i32, ptr @gB1951 %c = load i32, ptr @gC1952 %d = load i32, ptr @gD1953 1954 %x = add nuw i32 %a, %b1955 %y = add nuw i32 %c, %d1956 %res = add nuw i32 %x, %y1957 ret i32 %res1958}1959 1960define noundef ptr @gep_inbounds(ptr %p, i64 %index) {1961; CHECK-LABEL: 'gep_inbounds'1962; CHECK-NEXT: Classifying expressions for: @gep_inbounds1963; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %p, i64 %index1964; CHECK-NEXT: --> ((4 * %index)<nsw> + %p) U: full-set S: full-set1965; CHECK-NEXT: Determining loop execution counts for: @gep_inbounds1966;1967 %gep = getelementptr inbounds i32, ptr %p, i64 %index1968 ret ptr %gep1969}1970 1971define noundef ptr @gep_inbounds_nneg(ptr %p, i32 %index) {1972; CHECK-LABEL: 'gep_inbounds_nneg'1973; CHECK-NEXT: Classifying expressions for: @gep_inbounds_nneg1974; CHECK-NEXT: %index.ext = zext i32 %index to i641975; CHECK-NEXT: --> (zext i32 %index to i64) U: [0,4294967296) S: [0,4294967296)1976; CHECK-NEXT: %gep = getelementptr inbounds i32, ptr %p, i64 %index.ext1977; CHECK-NEXT: --> ((4 * (zext i32 %index to i64))<nuw><nsw> + %p)<nuw> U: full-set S: full-set1978; CHECK-NEXT: Determining loop execution counts for: @gep_inbounds_nneg1979;1980 %index.ext = zext i32 %index to i641981 %gep = getelementptr inbounds i32, ptr %p, i64 %index.ext1982 ret ptr %gep1983}1984 1985define noundef ptr @gep_nusw(ptr %p, i64 %index) {1986; CHECK-LABEL: 'gep_nusw'1987; CHECK-NEXT: Classifying expressions for: @gep_nusw1988; CHECK-NEXT: %gep = getelementptr nusw i32, ptr %p, i64 %index1989; CHECK-NEXT: --> ((4 * %index)<nsw> + %p) U: full-set S: full-set1990; CHECK-NEXT: Determining loop execution counts for: @gep_nusw1991;1992 %gep = getelementptr nusw i32, ptr %p, i64 %index1993 ret ptr %gep1994}1995 1996define noundef ptr @gep_nusw_nneg(ptr %p, i32 %index) {1997; CHECK-LABEL: 'gep_nusw_nneg'1998; CHECK-NEXT: Classifying expressions for: @gep_nusw_nneg1999; CHECK-NEXT: %index.ext = zext i32 %index to i642000; CHECK-NEXT: --> (zext i32 %index to i64) U: [0,4294967296) S: [0,4294967296)2001; CHECK-NEXT: %gep = getelementptr nusw i32, ptr %p, i64 %index.ext2002; CHECK-NEXT: --> ((4 * (zext i32 %index to i64))<nuw><nsw> + %p)<nuw> U: full-set S: full-set2003; CHECK-NEXT: Determining loop execution counts for: @gep_nusw_nneg2004;2005 %index.ext = zext i32 %index to i642006 %gep = getelementptr nusw i32, ptr %p, i64 %index.ext2007 ret ptr %gep2008}2009 2010define noundef ptr @gep_nuw(ptr %p, i64 %index) {2011; CHECK-LABEL: 'gep_nuw'2012; CHECK-NEXT: Classifying expressions for: @gep_nuw2013; CHECK-NEXT: %gep = getelementptr nuw i32, ptr %p, i64 %index2014; CHECK-NEXT: --> ((4 * %index)<nuw> + %p)<nuw> U: full-set S: full-set2015; CHECK-NEXT: Determining loop execution counts for: @gep_nuw2016;2017 %gep = getelementptr nuw i32, ptr %p, i64 %index2018 ret ptr %gep2019}2020 2021define noundef ptr @gep_nusw_nuw(ptr %p, i64 %index) {2022; CHECK-LABEL: 'gep_nusw_nuw'2023; CHECK-NEXT: Classifying expressions for: @gep_nusw_nuw2024; CHECK-NEXT: %gep = getelementptr nusw nuw i32, ptr %p, i64 %index2025; CHECK-NEXT: --> ((4 * %index)<nuw><nsw> + %p)<nuw> U: full-set S: full-set2026; CHECK-NEXT: Determining loop execution counts for: @gep_nusw_nuw2027;2028 %gep = getelementptr nusw nuw i32, ptr %p, i64 %index2029 ret ptr %gep2030}2031 2032define ptr @gep_nusw_nuw_missing_noundef(ptr %p, i64 %index) {2033; CHECK-LABEL: 'gep_nusw_nuw_missing_noundef'2034; CHECK-NEXT: Classifying expressions for: @gep_nusw_nuw_missing_noundef2035; CHECK-NEXT: %gep = getelementptr nusw nuw i32, ptr %p, i64 %index2036; CHECK-NEXT: --> ((4 * %index) + %p) U: full-set S: full-set2037; CHECK-NEXT: Determining loop execution counts for: @gep_nusw_nuw_missing_noundef2038;2039 %gep = getelementptr nusw nuw i32, ptr %p, i64 %index2040 ret ptr %gep2041}2042 2043define void @addrec_gep_inbounds_nneg(ptr %p, ptr %end) {2044; CHECK-LABEL: 'addrec_gep_inbounds_nneg'2045; CHECK-NEXT: Classifying expressions for: @addrec_gep_inbounds_nneg2046; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2047; CHECK-NEXT: --> {%p,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }2048; CHECK-NEXT: %iv.next = getelementptr inbounds i32, ptr %iv, i64 12049; CHECK-NEXT: --> {(4 + %p)<nuw>,+,4}<nuw><%loop> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }2050; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_inbounds_nneg2051; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)2052; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 46116860184273879032053; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)2054; CHECK-NEXT: Loop %loop: Trip multiple is 12055;2056entry:2057 br label %loop2058loop:2059 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2060 %iv.next = getelementptr inbounds i32, ptr %iv, i64 12061 %cmp = icmp ne ptr %iv.next, %end2062 br i1 %cmp, label %loop, label %exit2063exit:2064 ret void2065}2066 2067define void @addrec_gep_inbounds_neg(ptr %p, ptr %end) {2068; CHECK-LABEL: 'addrec_gep_inbounds_neg'2069; CHECK-NEXT: Classifying expressions for: @addrec_gep_inbounds_neg2070; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2071; CHECK-NEXT: --> {%p,+,-4}<nw><%loop> U: full-set S: full-set Exits: ((-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }2072; CHECK-NEXT: %iv.next = getelementptr inbounds i32, ptr %iv, i64 -12073; CHECK-NEXT: --> {(-4 + %p),+,-4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }2074; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_inbounds_neg2075; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)2076; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 46116860184273879032077; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)2078; CHECK-NEXT: Loop %loop: Trip multiple is 12079;2080entry:2081 br label %loop2082loop:2083 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2084 %iv.next = getelementptr inbounds i32, ptr %iv, i64 -12085 %cmp = icmp ne ptr %iv.next, %end2086 br i1 %cmp, label %loop, label %exit2087exit:2088 ret void2089}2090 2091define void @addrec_gep_nusw_nneg(ptr %p, ptr %end) {2092; CHECK-LABEL: 'addrec_gep_nusw_nneg'2093; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_nneg2094; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2095; CHECK-NEXT: --> {%p,+,4}<nuw><%loop> U: full-set S: full-set Exits: ((4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }2096; CHECK-NEXT: %iv.next = getelementptr nusw i32, ptr %iv, i64 12097; CHECK-NEXT: --> {(4 + %p)<nuw>,+,4}<nuw><%loop> U: [4,0) S: [4,0) Exits: (4 + (4 * ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4))<nuw> + %p) LoopDispositions: { %loop: Computable }2098; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_nneg2099; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)2100; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 46116860184273879032101; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %p to i64)) + (ptrtoint ptr %end to i64)) /u 4)2102; CHECK-NEXT: Loop %loop: Trip multiple is 12103;2104entry:2105 br label %loop2106loop:2107 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2108 %iv.next = getelementptr nusw i32, ptr %iv, i64 12109 %cmp = icmp ne ptr %iv.next, %end2110 br i1 %cmp, label %loop, label %exit2111exit:2112 ret void2113}2114 2115define void @addrec_gep_nusw_neg(ptr %p, ptr %end) {2116; CHECK-LABEL: 'addrec_gep_nusw_neg'2117; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_neg2118; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2119; CHECK-NEXT: --> {%p,+,-4}<nw><%loop> U: full-set S: full-set Exits: ((-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }2120; CHECK-NEXT: %iv.next = getelementptr nusw i32, ptr %iv, i64 -12121; CHECK-NEXT: --> {(-4 + %p),+,-4}<nw><%loop> U: full-set S: full-set Exits: (-4 + (-4 * ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)) + %p) LoopDispositions: { %loop: Computable }2122; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_neg2123; CHECK-NEXT: Loop %loop: backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)2124; CHECK-NEXT: Loop %loop: constant max backedge-taken count is i64 46116860184273879032125; CHECK-NEXT: Loop %loop: symbolic max backedge-taken count is ((-4 + (-1 * (ptrtoint ptr %end to i64)) + (ptrtoint ptr %p to i64)) /u 4)2126; CHECK-NEXT: Loop %loop: Trip multiple is 12127;2128entry:2129 br label %loop2130loop:2131 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2132 %iv.next = getelementptr nusw i32, ptr %iv, i64 -12133 %cmp = icmp ne ptr %iv.next, %end2134 br i1 %cmp, label %loop, label %exit2135exit:2136 ret void2137}2138 2139define void @addrec_gep_nuw(ptr %p, ptr %end, i64 %step) {2140; CHECK-LABEL: 'addrec_gep_nuw'2141; CHECK-NEXT: Classifying expressions for: @addrec_gep_nuw2142; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2143; CHECK-NEXT: --> {%p,+,(4 * %step)<nuw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }2144; CHECK-NEXT: %iv.next = getelementptr nuw i32, ptr %iv, i64 %step2145; CHECK-NEXT: --> {((4 * %step)<nuw> + %p)<nuw>,+,(4 * %step)<nuw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }2146; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nuw2147; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.2148; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.2149; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.2150;2151entry:2152 br label %loop2153loop:2154 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2155 %iv.next = getelementptr nuw i32, ptr %iv, i64 %step2156 %cmp = icmp ne ptr %iv.next, %end2157 br i1 %cmp, label %loop, label %exit2158exit:2159 ret void2160}2161 2162define void @addrec_gep_nusw_nuw(ptr %p, ptr %end, i64 %step) {2163; CHECK-LABEL: 'addrec_gep_nusw_nuw'2164; CHECK-NEXT: Classifying expressions for: @addrec_gep_nusw_nuw2165; CHECK-NEXT: %iv = phi ptr [ %p, %entry ], [ %iv.next, %loop ]2166; CHECK-NEXT: --> {%p,+,(4 * %step)<nuw><nsw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }2167; CHECK-NEXT: %iv.next = getelementptr nusw nuw i32, ptr %iv, i64 %step2168; CHECK-NEXT: --> {((4 * %step)<nuw><nsw> + %p)<nuw>,+,(4 * %step)<nuw><nsw>}<nuw><%loop> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %loop: Computable }2169; CHECK-NEXT: Determining loop execution counts for: @addrec_gep_nusw_nuw2170; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.2171; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.2172; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.2173;2174entry:2175 br label %loop2176loop:2177 %iv = phi ptr [ %p, %entry], [ %iv.next, %loop ]2178 %iv.next = getelementptr nusw nuw i32, ptr %iv, i64 %step2179 %cmp = icmp ne ptr %iv.next, %end2180 br i1 %cmp, label %loop, label %exit2181exit:2182 ret void2183}2184