@@ -304,14 +304,14 @@ define i32 @test10(i1 zeroext %flag, i32 %x, ptr %y, ptr %s) {
304304; CHECK-NEXT: br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
305305; CHECK: if.then:
306306; CHECK-NEXT: call void @bar(i32 5)
307+ ; CHECK-NEXT: store volatile i32 [[X:%.*]], ptr [[S:%.*]], align 4
307308; CHECK-NEXT: br label [[IF_END:%.*]]
308309; CHECK: if.else:
309310; CHECK-NEXT: call void @bar(i32 6)
310- ; CHECK-NEXT: [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S:%.*]], i32 0, i32 1
311+ ; CHECK-NEXT: [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S]], i32 0, i32 1
312+ ; CHECK-NEXT: store volatile i32 [[X]], ptr [[GEPB]], align 4
311313; CHECK-NEXT: br label [[IF_END]]
312314; CHECK: if.end:
313- ; CHECK-NEXT: [[GEPB_SINK:%.*]] = phi ptr [ [[GEPB]], [[IF_ELSE]] ], [ [[S]], [[IF_THEN]] ]
314- ; CHECK-NEXT: store volatile i32 [[X:%.*]], ptr [[GEPB_SINK]], align 4
315315; CHECK-NEXT: ret i32 1
316316;
317317entry:
@@ -518,23 +518,25 @@ declare void @llvm.dbg.value(metadata, metadata, metadata)
518518!11 = !DILocation (line: 1 , column: 14 , scope: !8 )
519519
520520
521- ; The load should be commoned.
521+ ; The load should not be commoned, as it will get separated from the GEP
522+ ; instruction producing the address.
522523define i32 @test15 (i1 zeroext %flag , i32 %w , i32 %x , i32 %y , ptr %s ) {
523524; CHECK-LABEL: @test15(
524525; CHECK-NEXT: entry:
525526; CHECK-NEXT: br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
526527; CHECK: if.then:
527528; CHECK-NEXT: call void @bar(i32 1)
529+ ; CHECK-NEXT: [[SV1:%.*]] = load i32, ptr [[S:%.*]], align 4
528530; CHECK-NEXT: br label [[IF_END:%.*]]
529531; CHECK: if.else:
530532; CHECK-NEXT: call void @bar(i32 4)
531- ; CHECK-NEXT: [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S:%.*]], i32 0, i32 1
533+ ; CHECK-NEXT: [[GEPB:%.*]] = getelementptr inbounds [[STRUCT_ANON:%.*]], ptr [[S]], i32 0, i32 1
534+ ; CHECK-NEXT: [[SV2:%.*]] = load i32, ptr [[GEPB]], align 4
532535; CHECK-NEXT: br label [[IF_END]]
533536; CHECK: if.end:
534- ; CHECK-NEXT: [[GEPB_SINK :%.*]] = phi ptr [ [[GEPB ]], [[IF_ELSE]] ], [ [[S ]], [[IF_THEN]] ]
537+ ; CHECK-NEXT: [[SV2_SINK :%.*]] = phi i32 [ [[SV2 ]], [[IF_ELSE]] ], [ [[SV1 ]], [[IF_THEN]] ]
535538; CHECK-NEXT: [[DOTSINK:%.*]] = phi i64 [ 57, [[IF_ELSE]] ], [ 56, [[IF_THEN]] ]
536- ; CHECK-NEXT: [[SV2:%.*]] = load i32, ptr [[GEPB_SINK]], align 4
537- ; CHECK-NEXT: [[EXT2:%.*]] = zext i32 [[SV2]] to i64
539+ ; CHECK-NEXT: [[EXT2:%.*]] = zext i32 [[SV2_SINK]] to i64
538540; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i64 [[EXT2]], [[DOTSINK]]
539541; CHECK-NEXT: ret i32 1
540542;
@@ -1803,17 +1805,19 @@ define i64 @multi_use_in_block_inconsistent(i1 %cond, ptr %p, i64 %a, i64 %b) {
18031805; CHECK: if:
18041806; CHECK-NEXT: call void @dummy()
18051807; CHECK-NEXT: [[GEP1_A:%.*]] = getelementptr i8, ptr [[P:%.*]], i64 [[A:%.*]]
1808+ ; CHECK-NEXT: [[V_A:%.*]] = load i64, ptr [[GEP1_A]], align 8
1809+ ; CHECK-NEXT: [[GEP2_A:%.*]] = getelementptr i8, ptr [[GEP1_A]], i64 [[V_A]]
18061810; CHECK-NEXT: br label [[JOIN:%.*]]
18071811; CHECK: else:
18081812; CHECK-NEXT: [[GEP1_B:%.*]] = getelementptr i8, ptr [[P]], i64 [[A]]
1813+ ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[P]], align 8
1814+ ; CHECK-NEXT: [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B]], i64 [[V_B]]
18091815; CHECK-NEXT: br label [[JOIN]]
18101816; CHECK: join:
1811- ; CHECK-NEXT: [[P_SINK:%.*]] = phi ptr [ [[P]], [[ELSE]] ], [ [[GEP1_A]], [[IF]] ]
1812- ; CHECK-NEXT: [[GEP1_B_SINK:%.*]] = phi ptr [ [[GEP1_B]], [[ELSE]] ], [ [[GEP1_A]], [[IF]] ]
1813- ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[P_SINK]], align 8
1814- ; CHECK-NEXT: [[GEP2_B:%.*]] = getelementptr i8, ptr [[GEP1_B_SINK]], i64 [[V_B]]
1815- ; CHECK-NEXT: call void @use.ptr(ptr [[GEP2_B]])
1816- ; CHECK-NEXT: ret i64 [[V_B]]
1817+ ; CHECK-NEXT: [[PHI1:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1818+ ; CHECK-NEXT: [[PHI2:%.*]] = phi ptr [ [[GEP2_A]], [[IF]] ], [ [[GEP2_B]], [[ELSE]] ]
1819+ ; CHECK-NEXT: call void @use.ptr(ptr [[PHI2]])
1820+ ; CHECK-NEXT: ret i64 [[PHI1]]
18171821;
18181822 br i1 %cond , label %if , label %else
18191823
@@ -1873,14 +1877,15 @@ define i64 @load_with_non_sunk_gep_both(i1 %cond, ptr %p.a, ptr %p.b, i64 %a, i6
18731877; CHECK: if:
18741878; CHECK-NEXT: call void @dummy()
18751879; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1880+ ; CHECK-NEXT: [[V_A:%.*]] = load i64, ptr [[GEP_A]], align 8
18761881; CHECK-NEXT: br label [[JOIN:%.*]]
18771882; CHECK: else:
18781883; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1884+ ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[GEP_B]], align 8
18791885; CHECK-NEXT: br label [[JOIN]]
18801886; CHECK: join:
1881- ; CHECK-NEXT: [[GEP_B_SINK:%.*]] = phi ptr [ [[GEP_B]], [[ELSE]] ], [ [[GEP_A]], [[IF]] ]
1882- ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[GEP_B_SINK]], align 8
1883- ; CHECK-NEXT: ret i64 [[V_B]]
1887+ ; CHECK-NEXT: [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1888+ ; CHECK-NEXT: ret i64 [[V]]
18841889;
18851890 br i1 %cond , label %if , label %else
18861891
@@ -1905,14 +1910,15 @@ define i64 @load_with_non_sunk_gep_left(i1 %cond, ptr %p.a, ptr %p.b, i64 %b) {
19051910; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE:%.*]]
19061911; CHECK: if:
19071912; CHECK-NEXT: call void @dummy()
1913+ ; CHECK-NEXT: [[V_A:%.*]] = load i64, ptr [[P_A:%.*]], align 8
19081914; CHECK-NEXT: br label [[JOIN:%.*]]
19091915; CHECK: else:
19101916; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1917+ ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[GEP_B]], align 8
19111918; CHECK-NEXT: br label [[JOIN]]
19121919; CHECK: join:
1913- ; CHECK-NEXT: [[GEP_B_SINK:%.*]] = phi ptr [ [[GEP_B]], [[ELSE]] ], [ [[P_A:%.*]], [[IF]] ]
1914- ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[GEP_B_SINK]], align 8
1915- ; CHECK-NEXT: ret i64 [[V_B]]
1920+ ; CHECK-NEXT: [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1921+ ; CHECK-NEXT: ret i64 [[V]]
19161922;
19171923 br i1 %cond , label %if , label %else
19181924
@@ -1933,15 +1939,18 @@ join:
19331939
19341940define i64 @load_with_non_sunk_gep_right (i1 %cond , ptr %p.a , ptr %p.b , i64 %a ) {
19351941; CHECK-LABEL: @load_with_non_sunk_gep_right(
1936- ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[JOIN :%.*]]
1942+ ; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF:%.*]], label [[ELSE :%.*]]
19371943; CHECK: if:
19381944; CHECK-NEXT: call void @dummy()
19391945; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1946+ ; CHECK-NEXT: [[V_A:%.*]] = load i64, ptr [[GEP_A]], align 8
1947+ ; CHECK-NEXT: br label [[JOIN:%.*]]
1948+ ; CHECK: else:
1949+ ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[P_B:%.*]], align 8
19401950; CHECK-NEXT: br label [[JOIN]]
19411951; CHECK: join:
1942- ; CHECK-NEXT: [[P_B_SINK:%.*]] = phi ptr [ [[GEP_A]], [[IF]] ], [ [[P_B:%.*]], [[TMP0:%.*]] ]
1943- ; CHECK-NEXT: [[V_B:%.*]] = load i64, ptr [[P_B_SINK]], align 8
1944- ; CHECK-NEXT: ret i64 [[V_B]]
1952+ ; CHECK-NEXT: [[V:%.*]] = phi i64 [ [[V_A]], [[IF]] ], [ [[V_B]], [[ELSE]] ]
1953+ ; CHECK-NEXT: ret i64 [[V]]
19451954;
19461955 br i1 %cond , label %if , label %else
19471956
@@ -1966,13 +1975,13 @@ define void @store_with_non_sunk_gep(i1 %cond, ptr %p.a, ptr %p.b, i64 %a, i64 %
19661975; CHECK: if:
19671976; CHECK-NEXT: call void @dummy()
19681977; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i8, ptr [[P_A:%.*]], i64 [[A:%.*]]
1978+ ; CHECK-NEXT: store i64 0, ptr [[GEP_A]], align 8
19691979; CHECK-NEXT: br label [[JOIN:%.*]]
19701980; CHECK: else:
19711981; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr i8, ptr [[P_B:%.*]], i64 [[B:%.*]]
1982+ ; CHECK-NEXT: store i64 0, ptr [[GEP_B]], align 8
19721983; CHECK-NEXT: br label [[JOIN]]
19731984; CHECK: join:
1974- ; CHECK-NEXT: [[GEP_B_SINK:%.*]] = phi ptr [ [[GEP_B]], [[ELSE]] ], [ [[GEP_A]], [[IF]] ]
1975- ; CHECK-NEXT: store i64 0, ptr [[GEP_B_SINK]], align 8
19761985; CHECK-NEXT: ret void
19771986;
19781987 br i1 %cond , label %if , label %else
0 commit comments