@@ -309,3 +309,143 @@ if.then.y:
309309exit:
310310  ret  i1  %cmp.y 
311311}
312+ 
313+ declare  void  @foo ()
314+ declare  void  @bar () #1 
315+ 
316+ ; Test that two if-regions are not merged when there's potential aliasing 
317+ ; between a store in the first if-region and a load in the second if-region's header 
318+ define  i32  @test_alias (i32  %a , i32  %b , ptr  %p1 , ptr  %p2 ) {
319+ ; CHECK-LABEL: define i32 @test_alias 
320+ ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) { 
321+ ; CHECK-NEXT:  entry: 
322+ ; CHECK-NEXT:    store i32 42, ptr [[P1]], align 4 
323+ ; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0 
324+ ; CHECK-NEXT:    br i1 [[COND1]], label [[IF_THEN1:%.*]], label [[IF_END1:%.*]] 
325+ ; CHECK:       if.then1: 
326+ ; CHECK-NEXT:    store i32 100, ptr [[P2]], align 4 
327+ ; CHECK-NEXT:    br label [[IF_END1]] 
328+ ; CHECK:       if.end1: 
329+ ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[P1]], align 4 
330+ ; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0 
331+ ; CHECK-NEXT:    br i1 [[COND2]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]] 
332+ ; CHECK:       if.then2: 
333+ ; CHECK-NEXT:    store i32 100, ptr [[P2]], align 4 
334+ ; CHECK-NEXT:    br label [[IF_END2]] 
335+ ; CHECK:       if.end2: 
336+ ; CHECK-NEXT:    ret i32 0 
337+ ; 
338+ entry:
339+   store  i32  42 , ptr  %p1 
340+   %cond1  = icmp  eq  i32  %a , 0 
341+   br  i1  %cond1 , label  %if.then1 , label  %if.end1 
342+ 
343+ if.then1:
344+   store  i32  100 , ptr  %p2   ; May alias with the load below 
345+   br  label  %if.end1 
346+ 
347+ if.end1:
348+   %val  = load  i32 , ptr  %p1   ; This load prevents merging due to potential alias 
349+   %cond2  = icmp  eq  i32  %b , 0 
350+   br  i1  %cond2 , label  %if.then2 , label  %if.end2 
351+ 
352+ if.then2:
353+   store  i32  100 , ptr  %p2 
354+   br  label  %if.end2 
355+ 
356+ if.end2:
357+   ret  i32  0 
358+ }
359+ 
360+ ; Test that two if-regions are not merged when there's potential aliasing 
361+ ; between a store in the first if-region and a function call in the second if-region's header 
362+ define  i32  @test_alias_2 (i32  %a , i32  %b ) {
363+ ; CHECK-LABEL: define i32 @test_alias_2 
364+ ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 
365+ ; CHECK-NEXT:  entry: 
366+ ; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4 
367+ ; CHECK-NEXT:    store i32 42, ptr [[P]], align 4 
368+ ; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0 
369+ ; CHECK-NEXT:    br i1 [[COND1]], label [[IF_THEN1:%.*]], label [[IF_END1:%.*]] 
370+ ; CHECK:       if.then1: 
371+ ; CHECK-NEXT:    store i32 100, ptr @g, align 4 
372+ ; CHECK-NEXT:    br label [[IF_END1]] 
373+ ; CHECK:       if.end1: 
374+ ; CHECK-NEXT:    call void @foo() 
375+ ; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0 
376+ ; CHECK-NEXT:    br i1 [[COND2]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]] 
377+ ; CHECK:       if.then2: 
378+ ; CHECK-NEXT:    store i32 100, ptr @g, align 4 
379+ ; CHECK-NEXT:    br label [[IF_END2]] 
380+ ; CHECK:       if.end2: 
381+ ; CHECK-NEXT:    ret i32 0 
382+ ; 
383+ entry:
384+   %p  = alloca  i32 
385+   store  i32  42 , ptr  %p 
386+   %cond1  = icmp  eq  i32  %a , 0 
387+   br  i1  %cond1 , label  %if.then1 , label  %if.end1 
388+ 
389+ if.then1:
390+   store  i32  100 , ptr  @g 
391+   br  label  %if.end1 
392+ 
393+ if.end1:
394+   call  void  @foo ()
395+   %cond2  = icmp  eq  i32  %b , 0 
396+   br  i1  %cond2 , label  %if.then2 , label  %if.end2 
397+ 
398+ if.then2:
399+   store  i32  100 , ptr  @g 
400+   br  label  %if.end2 
401+ 
402+ if.end2:
403+   ret  i32  0 
404+ }
405+ 
406+ ; Test that two if-regions are merged when there's no potential aliasing 
407+ ; between a store in the first if-region and a load in the second if-region's header 
408+ define  i32  @test_no_alias (i32  %a , i32  %b ) {
409+ ; CHECK-LABEL: define i32 @test_no_alias 
410+ ; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) { 
411+ ; CHECK-NEXT:  entry: 
412+ ; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4 
413+ ; CHECK-NEXT:    store i32 42, ptr [[P]], align 4 
414+ ; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0 
415+ ; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr @g, align 4 
416+ ; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0 
417+ ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND1]], [[COND2]] 
418+ ; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]] 
419+ ; CHECK:       if.then2: 
420+ ; CHECK-NEXT:    store i32 100, ptr [[P]], align 4 
421+ ; CHECK-NEXT:    call void @bar() 
422+ ; CHECK-NEXT:    br label [[IF_END2]] 
423+ ; CHECK:       if.end2: 
424+ ; CHECK-NEXT:    ret i32 0 
425+ ; 
426+ entry:
427+   %p  = alloca  i32 
428+   store  i32  42 , ptr  %p 
429+   %cond1  = icmp  eq  i32  %a , 0 
430+   br  i1  %cond1 , label  %if.then1 , label  %if.end1 
431+ 
432+ if.then1:
433+   store  i32  100 , ptr  %p   ; No alias with the load below 
434+   call  void  @bar () ; No alias with the load below since it's a pure function 
435+   br  label  %if.end1 
436+ 
437+ if.end1:
438+   %val  = load  i32 , ptr  @g 
439+   %cond2  = icmp  eq  i32  %b , 0 
440+   br  i1  %cond2 , label  %if.then2 , label  %if.end2 
441+ 
442+ if.then2:
443+   store  i32  100 , ptr  %p 
444+   call  void  @bar ()
445+   br  label  %if.end2 
446+ 
447+ if.end2:
448+   ret  i32  0 
449+ }
450+ 
451+ attributes  #1  = { readnone  willreturn nounwind  }
0 commit comments