@@ -367,6 +367,77 @@ loop:
367367 br label %loop
368368}
369369
370+ ; FIXME: Hoist ADD and copy NUW NSW if both ops have it.
371+ define void @add_nuw_nsw (i64 %c1 , i64 %c2 ) {
372+ ; CHECK-LABEL: @add_nuw_nsw(
373+ ; CHECK-NEXT: entry:
374+ ; CHECK-NEXT: [[INVARIANT_OP:%.*]] = add nuw i64 [[C1:%.*]], [[C2:%.*]]
375+ ; CHECK-NEXT: br label [[LOOP:%.*]]
376+ ; CHECK: loop:
377+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
378+ ; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw nsw i64 [[INDEX]], [[C1]]
379+ ; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
380+ ; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
381+ ; CHECK-NEXT: br label [[LOOP]]
382+ ;
383+ entry:
384+ br label %loop
385+
386+ loop:
387+ %index = phi i64 [ 0 , %entry ], [ %index.next , %loop ]
388+ %step.add = add nuw nsw i64 %index , %c1
389+ call void @use (i64 %step.add )
390+ %index.next = add nuw nsw i64 %step.add , %c2
391+ br label %loop
392+ }
393+
394+ define void @add_both_nsw_first_nuw (i64 %c1 , i64 %c2 ) {
395+ ; CHECK-LABEL: @add_both_nsw_first_nuw(
396+ ; CHECK-NEXT: entry:
397+ ; CHECK-NEXT: [[INVARIANT_OP:%.*]] = add i64 [[C1:%.*]], [[C2:%.*]]
398+ ; CHECK-NEXT: br label [[LOOP:%.*]]
399+ ; CHECK: loop:
400+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
401+ ; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw nsw i64 [[INDEX]], [[C1]]
402+ ; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
403+ ; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
404+ ; CHECK-NEXT: br label [[LOOP]]
405+ ;
406+ entry:
407+ br label %loop
408+
409+ loop:
410+ %index = phi i64 [ 0 , %entry ], [ %index.next , %loop ]
411+ %step.add = add nuw nsw i64 %index , %c1
412+ call void @use (i64 %step.add )
413+ %index.next = add nsw i64 %step.add , %c2
414+ br label %loop
415+ }
416+
417+ define void @add_both_nsw_second_nuw (i64 %c1 , i64 %c2 ) {
418+ ; CHECK-LABEL: @add_both_nsw_second_nuw(
419+ ; CHECK-NEXT: entry:
420+ ; CHECK-NEXT: [[INVARIANT_OP:%.*]] = add i64 [[C1:%.*]], [[C2:%.*]]
421+ ; CHECK-NEXT: br label [[LOOP:%.*]]
422+ ; CHECK: loop:
423+ ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
424+ ; CHECK-NEXT: [[STEP_ADD:%.*]] = add nsw i64 [[INDEX]], [[C1]]
425+ ; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
426+ ; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
427+ ; CHECK-NEXT: br label [[LOOP]]
428+ ;
429+ entry:
430+ br label %loop
431+
432+ loop:
433+ %index = phi i64 [ 0 , %entry ], [ %index.next , %loop ]
434+ %step.add = add nsw i64 %index , %c1
435+ call void @use (i64 %step.add )
436+ %index.next = add nuw nsw i64 %step.add , %c2
437+ br label %loop
438+ }
439+
440+ ;
370441; Hoist MUL and drop NSW even if both ops have it.
371442define void @mul_no_nsw_2 (i64 %c1 , i64 %c2 ) {
372443; CHECK-LABEL: @mul_no_nsw_2(
0 commit comments